2014-09-20 62 views
6

更新:NSMutableAttributedString将不会显示从非零索引开始的属性

我创建了一个非常简单的独立项目来演示该错误。如果有人想拉同一件事,看看他们能否发现我出错的地方,我一定会很感激。没有太多代码需要查看。公开回购这里: https://github.com/reidnez/NSAttributedStringBugDemo

我在这里有一个很奇怪的问题:我有一个tableview。每个单元格有一个标题标签有1-3个字,和一个关键字标签有几个CSV关键字。我也有一个搜索栏。要求是,当用户键入搜索栏时,每个单元格的标题和关键字上的任何部分匹配都会突出显示。截图:

Everything looks as it should searching on "Fa"

"an" highlights keyword, but not title

第一图像是,好吧。在第二张图片中,标题标签的“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. 
} 
+0

Downvote with no comment?啧,谢谢。超级建设性!我不会再那样做......不管我做了什么? – 2014-09-20 22:34:29

+2

我看到与表格视图单元格的标签相同的东西。我可以强调文本的开始,但不是中间的。我建议制作一个简单的小测试应用程序,然后将错误报告提交给Apple。 – rmaddy 2014-09-20 22:40:15

+0

“这是苹果的错误”总是我最后的解决方案......我真的必须向自己证明情况是这样的(更有可能的是,小我在某处犯了一个错误)。但是如果你遇到过类似的问题,那实际上可能是正确的结论。独立的测试应用程序是一个好主意,我会这样做。谢谢! – 2014-09-20 22:42:17

回答

2

感谢您写这篇文章...以为我也疯了!

我想出了一个解决方法(阅读:黑客),而我们等待苹果官方的东西。

NSDictionary *hackAttribute = [NSDictionary dictionaryWithObjectsAndKeys: 
          [UIColor clearColor], NSBackgroundColorAttributeName, nil]; 

NSMutableAttributedString *attributedText = 
    [[NSMutableAttributedString alloc] initWithString:@"some text..."]; 
    [attributedAddressText setAttributes:hackAttribute range:NSMakeRange(0, attributedText.length)]; 
// Then set your other attributes as per normal 

希望有所帮助。

+0

谢谢!我实际上已经放弃了很久以前的工作,并开始研究其他事情。但是......只要我回家,我会测试这个(假设它有效)接受你的答案。 – 2015-01-09 16:59:41

+0

这个黑客为我工作.. – 2015-01-16 01:28:08

+0

@ReidBelton:lemme知道它是怎么回事:) – 2015-01-20 01:59:51