更新:NSMutableAttributedString将不会显示从非零索引开始的属性
我创建了一个非常简单的独立项目来演示该错误。如果有人想拉同一件事,看看他们能否发现我出错的地方,我一定会很感激。没有太多代码需要查看。公开回购这里: https://github.com/reidnez/NSAttributedStringBugDemo
我在这里有一个很奇怪的问题:我有一个tableview。每个单元格有一个标题标签有1-3个字,和一个关键字标签有几个CSV关键字。我也有一个搜索栏。要求是,当用户键入搜索栏时,每个单元格的标题和关键字上的任何部分匹配都会突出显示。截图:
第一图像是,好吧。在第二张图片中,标题标签的“an”应该突出显示。但是,正如你所看到的,不是那么多......
这个工作完全正确的“关键字”标签,你可以看到上面。这两个标签的属性字符串是由我写的类别(代码如下)创建的。两个字符串都调用了相同的方法,并且从调试器告诉我的行为看起来相同。用户界面讲述了不同的故事。
我已经遍历调试器多次,并且在所有情况下,属性字符串出现已被正确配置。我还验证了别的东西不是调用[tableView reloadData]
,我的代码中没有其他地方覆盖标签的值。这是怎么匹配“的”为“方”看在调试器,之前在cellForRowAtIndexPath
结束返回细胞:
(lldb) po customCell.entryTitleLabel.attributedText
F{
}an{
NSBackgroundColor = "UIDeviceRGBColorSpace 0.533333 0.835294 0.156863 1";
}g{
}
我看不错......这正是我想要的。但是当细胞呈现时,没有任何亮点可以看到!怪异的是,作为一个实验我尝试了标签设置,我就在cellForRow创造了一个完全任意attributedString:
NSMutableAttributedString *fake = [[NSMutableAttributedString alloc] initWithString:@"Fang"];
[fake addAttribute:NSBackgroundColorAttributeName value:MATCH_TEXT_HILIGHT_COLOR range:NSMakeRange(1, 2)];
customCell.entryTitleLabel.attributedText = fake;
这也将失败。根本没有突出显示...但我可以突出显示范围{0,1}到{0,fake.length}的任何子字符串,并且其行为与预期相同。 同样,它似乎拒绝突出显示任何不在索引0处开始的子字符串 - 但仅限于标题标签。
我在想我吗?我错过了什么?
下面是我的类别...但我相当有信心,问题不在于此,因为它对关键字字符串完美起作用,并且(再次)属性在单元格返回前似乎正确设置:
-(void)hilightMatchingSubstring:(NSString*)substring color:(UIColor*)hilightColor range:(NSRange)range
{
if ([self.string compare:substring options:NSCaseInsensitiveSearch] == NSOrderedSame) {
[self addAttribute:NSBackgroundColorAttributeName value:hilightColor range:NSMakeRange(0, self.length)];
return;
}
// Sanity check. Make sure a valid range has been passed so that we don't get out-of-bounds crashes. Default to return self wrapped in an attributed string with no attributes.
NSRange selfRange = NSMakeRange(0, self.length);
if (NSIntersectionRange(selfRange, range).length == 0) {
NSLog(@" \n\n\n*** Match range {%lu, %lu} does not intersect main string's range {%lu, %lu}. Aborting *** \n\n\n", (unsigned long)range.location, (unsigned long)range.length, (unsigned long)selfRange.location, (unsigned long)selfRange.length);
return;
}
if (substring.length > 0) {
NSRange movingRange = NSMakeRange(range.location, substring.length);
if (NSMaxRange(movingRange) > self.length) {
return;
}
NSString *movingString = [self.string substringWithRange:movingRange];
while (NSMaxRange(movingRange) < NSMaxRange(range)) {
if ([movingString compare:substring options:NSCaseInsensitiveSearch] == NSOrderedSame) {
[self addAttribute:NSBackgroundColorAttributeName value:hilightColor range:movingRange];
}
movingRange = NSMakeRange(movingRange.location + 1, substring.length);
movingString = [self.string substringWithRange:movingRange];
}
} // This is fine...string leaves properly attributed.
}
Downvote with no comment?啧,谢谢。超级建设性!我不会再那样做......不管我做了什么? – 2014-09-20 22:34:29
我看到与表格视图单元格的标签相同的东西。我可以强调文本的开始,但不是中间的。我建议制作一个简单的小测试应用程序,然后将错误报告提交给Apple。 – rmaddy 2014-09-20 22:40:15
“这是苹果的错误”总是我最后的解决方案......我真的必须向自己证明情况是这样的(更有可能的是,小我在某处犯了一个错误)。但是如果你遇到过类似的问题,那实际上可能是正确的结论。独立的测试应用程序是一个好主意,我会这样做。谢谢! – 2014-09-20 22:42:17