我正在使用 NSAttributedString 对来自 API 的文本的某些部分(如 Twitter 上的“@mention”)进行着色。
API 为我提供了文本和代表文本中应着色的部分(或链接、标签等)的实体数组。
但有时,颜色会因为表情符号而被抵消。
例如,对于以下文本:
“@ericd 一些文字。@apero”
API 给出:
[
{
“文本”:“埃里克”,
“长度”:6,
“位置”:0
},
{
“文本”:“阿佩罗”,
“长度”:6,
“位置”:18
}
]
我使用 NSRange 成功将其转换为 NSAttributedString:
for m in entities.mentions {
let r = NSMakeRange(m.pos, m.len)
myAttributedString.addAttribute(NSForegroundColorAttributeName, value: someValue, range: r)
}
我们看到"pos": 18
是正确的,这是“@apero”开始的地方。正如预期的那样,彩色部分是“@ericd”和“@apero”。
但是当文本中使用某些特定的表情符号组合时,API 无法很好地转换为 NSATtributedString,颜色会发生偏移:
“@ericd 一些文字。????✌???? @apero”
gives:
[
{
“文本”:“埃里克”,
“长度”:6,
“位置”:0
},
{
“文本”:“阿佩罗”,
“长度”:6,
“位置”:22
}
]
"pos": 22
:API作者声明这是正确的,我理解他们的观点。
不幸的是, NSAttributedString 不同意,我的着色关闭了:
第二次提到的最后一个字符没有着色(因为“pos”由于表情符号而太短?)。
正如您可能已经猜到的那样,我无法以任何方式改变 API 的行为方式,我必须在客户端进行调整。
除此之外...我不知道该怎么办。我是否应该尝试检测文本中的表情符号类型,并在出现有问题的表情符号时手动修改提及的位置?但是检测哪些表情符号改变位置、哪些不改变位置的标准是什么?以及如何决定我需要多少补偿?也许问题是由 NSAttributedString 引起的?
我知道这与曾经组成的表情符号长度与它们作为离散字符的长度相比有关,但是......好吧......我迷路了(叹气)。
请注意,我尝试实施类似的解决方案这个东西 https://github.com/berg/ANAPIRangeAdapter/blob/master/ANAPIRangeAdapter/NSString%2BANAPIRangeAdapter.m因为我的 API 与这个兼容,但它只部分工作,一些表情符号仍然破坏索引: