UILabel 在第二次设置 attributedText 时丢失文本属性

UILabel loses text attributes the second time attributedText is set

我正在使用 iOS 中介绍的 UISearchController API 实现搜索 8. 我有一个 UITableViewController 子类既充当搜索结果控制器又充当搜索结果更新器。该控制器负责在 table 视图中显示搜索结果。

每次 searchBar 中的文本更改时,搜索 API 都会调用我的 table 视图控制器上的 UISearchControllerUpdating 方法 -updateSearchResultsForSearchController:。在这个方法中,我根据新的搜索字符串更新搜索结果,然后调用 [self.tableview reloadData].

我还试图在结果列表中突出显示搜索字符串的出现。我通过将 table 视图单元格上的属性文本设置为包含高亮显示的属性字符串来实现此目的。

我看到以下行为:

  1. 第一次击键后,高亮显示正确
  2. 第二次击键后,所有突出显示都消失了,除了
  3. 如果一个单元格在字符串的开头有一个突出显示的区域,它将显示所有突出显示,即使在字符串的其余部分也是如此

经过反复试验,我发现这似乎与 table 视图或单元格没有任何关系,而与 UI 标签有关。似乎标签总是在第二次设置 attributedText 属性 时失去高亮显示。真的只能设置一次吗?

我的一些代码

Table查看数据源:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString* plainCell = @"plainCell";
    UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:plainCell];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:plainCell];
    }

    JFDHelpEntry* entry = searchResults[indexPath.row];
    cell.textLabel.attributedText = [self highlightedString:entry.title withSearchString:currentSearchString];

    return cell;
}

生成文字高亮的方法:

- (NSAttributedString*)highlightedString:(NSString*)string withSearchString:(NSString*)searchString
{
    NSMutableAttributedString* result = [[NSMutableAttributedString alloc] initWithString:string];
    NSArray* matchedRanges = [self rangesOfString:searchString inString:string];

    for (NSValue* rangeInABox in matchedRanges) {
        [result addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:[rangeInABox rangeValue]];
    }

    return result;
}

查找要突出显示的范围的方法:

- (NSArray*)rangesOfString:(NSString*)needle inString:(NSString*)haystack
{
    NSMutableArray* result = [NSMutableArray array];
    NSRange searchRange = NSMakeRange(0, haystack.length);
    NSRange foundRange;

    while (foundRange.location != NSNotFound) {
        foundRange = [haystack rangeOfString:needle options:NSCaseInsensitiveSearch range:searchRange];

        if (foundRange.location != NSNotFound) {
            [result addObject:[NSValue valueWithRange:foundRange]];

            searchRange.location = foundRange.location + foundRange.length;
        }

        searchRange.length = haystack.length - searchRange.location;
    }

    return result;
}

有什么想法吗?谢谢!

我现在确信我的问题是由 UIKit 中的错误引起的,我已经报告了该错误。可以看到on openradar.

解决方法是检查字符串的开头是否有高亮,如果没有,则添加范围为 0-1 的清晰背景颜色属性。