一不小心,在iOS富文本上栽了个跟头

故事是这样子的:现在有个列表,要实现搜索关键字高亮的效果,我们都知道,使用iOS的富文本可以很方便实现该效果。于是,我新建一个UITableViewCell,并在cell上添加一个UILabel,考虑到这个cell可能在项目中其他地方可以复用(在其他地方可能只是简单展示,不需要使用富文本),于是我这样子写:

在init方法中添加一个label并给基本属性font、textColor赋值:

```

_nameLabel = [[UILabel alloc]init];

_nameLabel.font = [UIFont systemFontOfSize:16];

_nameLabel.textColor = [UIColor blackColor];

[self.contentView addSubview:_nameLabel];

```

写一个刷新方法:

```

- (void)reloadWithContent:(NSString *)content keywords:(NSString *)keywords

{

NSDictionary *attributes = @;

NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc]initWithString:content attributes:attributes];

NSRange keyRange = [content rangeOfString:keywords];

if(keyRange.location != NSNotFound){

[attributedStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:keyRange];

[attributedStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:keyRange];

}

_nameLabel.attributedText = attributedStr;

}

```

这里可以看到,我为了方便在以后UI调整或需求变更的时候实现”一个属性的修改,只修改一个地方即可“,比如,如果某天UI要求修改默认字体颜色,我只需要在init方法中修改textColor属性即可。我这里在创建富文本的时候,给富文本设置默认的字体和颜色时,font和textColor直接从_nameLabel的属性中获取。

那么,请思考一下,我上面这种写法有什么毛病没有?为什么?

对富文本比较熟悉并且细心的你会发现这种写法会有问题,问题就在上面的偷懒写法那里,我们先看看demo的效果图:

你会发现,刚开始状态是对的,当你上下滑动的时候,cell进行复用了之后,cell的字体和颜色都变成高亮的状态了。这是为什么呢?当然是cell重用和设置富文本的问题。我们可以看到UILabel设置富文本的官方文档是这样说的:

```

This property is nil by default.

Assigning a new value to this property also replaces the value of the text property with the same string data, although without any formatting information. In addition, assigning a new a value updates the values in the font, textColor, and other style-related properties so that they reflect the style information starting at location 0 in the attributed string.

```

看到这里,一切都明白了,在给UILabel的attributedText属性赋值的时候,系统会自动用富文本字符串起始位置处的子字符串的样式来应用到整个UILabel的样式。也就是说设置attributedText之后,UILabel的font和textColor就已经被系统自动修改成位置处字符的font和textColor了,所以才会导致上面看到的效果。

问题找到了,那么针对这种情况我们怎么处理呢?在这里就不能再偷懒了,要么在cell的prepareForReuse方法中再次给UILabel的默认状态赋上默认值,要么在新建富文本的时候不要直接从label的属性中获取,老老实实新建跟默认状态值一样的UIFont和UIColor。唯一麻烦的就是以后需求改动之后,要记得同时修改这几个地方了。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180527G0VODT00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券