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

Posted

技术标签:

【中文标题】UILabel 在第二次设置属性文本时丢失文本属性【英文标题】:UILabel loses text attributes the second time attributedText is set 【发布时间】:2015-02-09 23:24:18 【问题描述】:

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

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

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

我看到以下行为:

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

经过反复试验,我发现这似乎与表格视图或单元格无关,而与 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;

有什么想法吗?谢谢!

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

以上是关于UILabel 在第二次设置属性文本时丢失文本属性的主要内容,如果未能解决你的问题,请参考以下文章

UILabel属性(文本标签)

UILabel 自动收缩不起作用

如何将 CGFloat 设置为 UILabel 的文本属性

如何在 Swift 中更改 UILabel 的文本属性?

设置为 nil 或 "" 时的 UILabel 文本属性使 UILabel 从视图中消失(Swift / Autolayout / iOS9.1)

Autolayout UILabel 高度在第二个视图外观上发生变化