美文网首页I love iOS
一不小心,在iOS富文本上栽了个跟头

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

作者: Code_Ninja | 来源:发表于2018-05-27 16:47 被阅读11次

    故事是这样子的:现在有个列表,要实现搜索关键字高亮的效果,我们都知道,使用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 = @{NSFontAttributeName:_nameLabel.font,
                                     NSForegroundColorAttributeName:_nameLabel.textColor,
                                     };
        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的效果图:

    iOS富文本.gif

    你会发现,刚开始状态是对的,当你上下滑动的时候,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属性赋值的时候,系统会自动用富文本字符串起始0位置处的子字符串的样式来应用到整个UILabel的样式。也就是说设置attributedText之后,UILabel的font和textColor就已经被系统自动修改成0位置处字符的font和textColor了,所以才会导致上面看到的效果。

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/wxabjftx.html