2013-03-09 61 views
4

我正在使用TTTAttributedLabel将格式应用于文本,但它似乎崩溃,因为我试图将格式应用于包含表情符号的范围。示例:带有EMOJI导致NSRange问​​题的文本字符串

NSString *text = @"@user1234 #hashtag"; // text.length reported as 22 by NSLog as each emoji is 2 chars in length 
cell.textLabel.text = text; 

int length = 8; 
int start = 13; 

NSRange *range = NSMakeRange(start, length); 

if (!NSEqualRanges(range, NSMakeRange(NSNotFound, 0))) { 
    // apply formatting to TTTAttributedLabel 
    [cell.textLabel addLinkToURL:[NSURL URLWithString:[NSString stringWithFormat:@"someaction://hashtag/%@", [cell.textLabel.text substringWithRange:range]]] withRange:range]; 
} 

注意:我传递了来自API的NSRange值以及文本字符串。

在上面我试图应用格式#hashtag。通常这工作正常,但因为我有字符串涉及表情符号,我相信范围标识试图格式化表情符号,因为它们实际上是UTF值,它在TTTAttributedLabel导致崩溃(它实际上挂起没有崩溃,但是。 ..)

奇怪的是,如果有1周的表情符号,但休息,如果有2

谁能帮我找出在这里做什么工作好?

+1

如果您要显示应用格式的代码,特别是代码“挂起”,这将更容易诊断。你在这里显示的代码都没有引用字符串。理想情况下,您应该能够创建一个非常短的程序来演示问题,以便其他人可以重现该问题。 – 2013-03-09 15:48:00

+0

添加上面显示我申请使用TTTAttributedLabel addLinkToUrl方法 – mootymoots 2013-03-09 16:00:07

回答

1

我假设这是来自Twitter API,并且您正尝试使用它们返回的实体字典。我刚刚编写代码来支持处理这些范围以及NSString版本的字符串范围。

我的做法是“修复”Twitter返回以应付额外字符的实体字典。由于各种原因,我无法共享代码,但这是我所做的:

  1. 制作实体字典的深层可变副本。
  2. 循环通过串的整个范围内,通过unicharunichar,这样做:
    1. 检查是否unichar是在代理对范围(0xd800 - >0xdfff)。
    2. 如果它是代理对码点,则遍历实体词典中的所有条目,并且如果它们大于字符串中的当前位置(根据unichar s),则将索引移位1。然后,将循环计数器加1以跳过此代理对的伙伴,因为它现在已被处理。
    3. 如果它不是代理对,则什么也不做。
  3. 循环遍历所有实体并检查它们是否都没有溢出字符串的末尾。他们不应该,而只是开始。我发现一些Twitter返回duff数据的情况。

我希望有帮助!我也希望有一天我可以开源这个代码,因为我认为它会非常有用!

+0

其实我试过这个,但是找到了一个更简单的解决方案。我没有使用twitter btw,但与实体类似。每个实体都有实体的文本,所以我只查找了整个字符串中的entity.text的范围,而BINGO则没有更多的问题。 :) – mootymoots 2013-03-09 23:11:47

+0

哦,太棒了,那很好,然后:-)。虽然我猜如果你有两个实体具有相同的文本但链接到不同的地方。不过,很高兴你解决了! – mattjgalloway 2013-03-10 08:47:10

3

问题是,字符串中Unicode值超过\ U10000或更高的任何Unicode字符在NSString中将显示为两个字符。

既然你想要格式化hashtag,你应该使用更多的动态方式来获取开始和长度值。用NSString rangeOfString找到#字符的位置。使用该结果和字符串的长度来获得所需的长度。

NSString *text = @"@user1234 #hashtag"; // text.length reported as 22 by NSLog as each emoji is 2 chars in length 
cell.textLabel.text = text; 

NSUInteger start = [text rangeOfString:@"#"]; 
if (start != NSNotFound) { 
    NSUInteger length = text.length - start; 
    NSRange *range = NSMakeRange(start, length); 
    // apply formatting to TTTAttributedLabel 
    [cell.textLabel addLinkToURL:[NSURL URLWithString:[NSString stringWithFormat:@"someaction://hashtag/%@", [cell.textLabel.text substringWithRange:range]]] withRange:range]; 
} 
+1

,如果有一个哈希标签,但可以有很多,并将匹配非哈希标签。我宁愿使用提供的范围,并根据表情符号在那里进行调整。 – mootymoots 2013-03-09 16:20:53

+2

正确的方法是扫描字符串以获取井号标签。如果字符串可以包含多个hashtag,那么您不能硬编码位置。您必须扫描该标签的字符串。正确使用'NSString rangeOfStringXXX'方法来查找所有这些方法。我只是给你找到一个例子。这很容易更新,使用循环,找到每个哈希标签。显然,长度的确定更多地涉及到然后只是到了字符串的末尾。 – rmaddy 2013-03-09 16:25:39

+0

我在上面添加了一个注释,它似乎只是一个问题,如果有两个表情符号在一起,它工作正常,如果有一个表情符号。 – mootymoots 2013-03-09 16:34:19