0

我正在使用 iOS 8 中引入的 UISearchController API 实现搜索。我有一个 UITableViewController 子类,它既可用作搜索结果控制器,也可用作搜索结果更新器。该控制器负责在表格视图中显示搜索结果。

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

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

我看到以下行为:

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

经过反复试验,我发现这似乎与表格视图或单元格无关,而与 UILabel 完全有关。第二次设置属性文本属性时,标签似乎总是失去突出显示。我真的只能设置一次吗?

我的一些代码

表视图数据源:

- (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;
}

有任何想法吗?谢谢!

4

1 回答 1

0

我现在确信我的问题是由我报告的 UIKit 中的错误引起的。你可以在 openradar 上看到它。

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

于 2015-02-10T21:50:01.173 回答