5

我正在使用 TTTAttributedLabel 将格式应用于文本,但它似乎崩溃了,因为我试图将格式应用于包含表情符号的范围。例子:

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 个则中断。

谁能帮我弄清楚在这里做什么?

4

2 回答 2

3

问题是字符串中任何 Unicode 值为 \U10000 或更高的 Unicode 字符将在NSString.

由于您要格式化主题标签,因此您应该使用更动态的方式来获取开始和长度值。用于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];
}
于 2013-03-09T16:18:00.807 回答
2

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

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

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

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

于 2013-03-09T16:52:35.220 回答