美文网首页自个儿读实用工具iOS之功能细节
富文本常用封装(NSAttributedString浅析)

富文本常用封装(NSAttributedString浅析)

作者: 王隆帅 | 来源:发表于2016-07-16 20:07 被阅读6018次

    最近经常遇到关于富文本的一些需求,特此封装了几个最常用的API分享给大家,但授之以鱼不如授之以渔,接下来会顺便谈谈NSAttributedString,确保你读了本篇文章能够自己封装关于富文本的API,本文封装API的示例Demo再此,拿去用吧!骚年们!

    一、常用需求封装

    • 需求:在我们日常开发中,某些句子中会有改变某些字颜色的需求,当然颜色一般而言就是为了着重强调,常为同一种颜色,所以下面代码是单纯改变一句话中的某些字的颜色
    
    /**
     *  单纯改变一句话中的某些字的颜色 
     *
     *  @param color    需要改变成的颜色
     *  @param totalStr 总的字符串
     *  @param subArray 需要改变颜色的文字数组
     *
     *  @return 生成的富文本
     */
    + (NSMutableAttributedString *)ls_changeCorlorWithColor:(UIColor *)color TotalString:(NSString *)totalStr SubStringArray:(NSArray *)subArray {
    
        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:totalStr];
        for (NSString *rangeStr in subArray) {
            
            NSRange range = [totalStr rangeOfString:rangeStr options:NSBackwardsSearch];
            [attributedStr addAttribute:NSForegroundColorAttributeName value:color range:range];
        }
        
        return attributedStr;
    }
    
    
    • 需求:需要更改字间距来适应整体UI
    
    /**
     *  单纯改变句子的字间距(需要 <CoreText/CoreText.h>)
     *
     *  @param totalString 需要更改的字符串
     *  @param space       字间距
     *
     *  @return 生成的富文本
     */
    + (NSMutableAttributedString *)ls_changeSpaceWithTotalString:(NSString *)totalString Space:(CGFloat)space {
    
        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:totalString];
        long number = space;
        CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);
        [attributedStr addAttribute:(id)kCTKernAttributeName value:(__bridge id)num range:NSMakeRange(0,[attributedStr length])];
        CFRelease(num);
        
        return attributedStr;
    }
    
    
    • 需求:需要改变行间距来适应整体UI
    
    /**
     *  单纯改变段落的行间距
     *
     *  @param totalString 需要更改的字符串
     *  @param lineSpace   行间距
     *
     *  @return 生成的富文本
     */
    + (NSMutableAttributedString *)ls_changeLineSpaceWithTotalString:(NSString *)totalString LineSpace:(CGFloat)lineSpace {
    
        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:totalString];
        
        NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        [paragraphStyle setLineSpacing:lineSpace];
        
        [attributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [totalString length])];
    
        return attributedStr;
    }
    
    
    • 需求:同时更改行间距和字间距
    /**
     *  同时更改行间距和字间距
     *
     *  @param totalString 需要改变的字符串
     *  @param lineSpace   行间距
     *  @param textSpace   字间距
     *
     *  @return 生成的富文本
     */
    + (NSMutableAttributedString *)ls_changeLineAndTextSpaceWithTotalString:(NSString *)totalString LineSpace:(CGFloat)lineSpace textSpace:(CGFloat)textSpace {
        
        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:totalString];
        
        NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        [paragraphStyle setLineSpacing:lineSpace];
        
        [attributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [totalString length])];
        
        long number = textSpace;
        CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);
        [attributedStr addAttribute:(id)kCTKernAttributeName value:(__bridge id)num range:NSMakeRange(0,[attributedStr length])];
        CFRelease(num);
        
        return attributedStr;
    }
    
    
    • 需求:更改某些文字的颜色并修改其字体,突出重点强调
    /**
     *  改变某些文字的颜色 并单独设置其字体
     *
     *  @param font        设置的字体
     *  @param color       颜色
     *  @param totalString 总的字符串
     *  @param subArray    想要变色的字符数组
     *
     *  @return 生成的富文本
     */
    + (NSMutableAttributedString *)ls_changeFontAndColor:(UIFont *)font Color:(UIColor *)color TotalString:(NSString *)totalString SubStringArray:(NSArray *)subArray {
        
        NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:totalString];
        
        for (NSString *rangeStr in subArray) {
            
            NSRange range = [totalString rangeOfString:rangeStr options:NSBackwardsSearch];
            
            [attributedStr addAttribute:NSForegroundColorAttributeName value:color range:range];
            [attributedStr addAttribute:NSFontAttributeName value:font range:range];
        }
        
        return attributedStr;
    }
    
    

    以上几种API综合效果图如下

    二、谈谈NSAttributedString

    1、初始化方法

    - (instancetype)initWithString:(NSString *)str;
    - (instancetype)initWithString:(NSString *)str attributes:(nullable NSDictionary<NSString *, id> *)attrs;
    - (instancetype)initWithAttributedString:(NSAttributedString *)attrStr;
    
    
    • 第一种使用字符串初始化初始化富文本
    • 第二种使用字符串及属性字典(就是配置富文本的相关属性)初始化富文本
    • 第三种就是用其他富文本初始化富文本

    2、常用操作API

    • 为某一范围内文字添加某个属性
    - (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range;
    
    

    示例:

    • 为某一范围内文字添加多个属性(两个API效果与格式一样)
    - (void)addAttributes:(NSDictionary<NSString *, id> *)attrs range:(NSRange)range;
    
    - (void)setAttributes:(nullable NSDictionary<NSString *, id> *)attrs range:(NSRange)range;
    
    

    示例:

    • 移除某范围内的某个属性(可与添加属性API对照,不在示例)
    - (void)removeAttribute:(NSString *)name range:(NSRange)range;
    
    
    • 其他部分API(见名知意,可与NSString对照不在赘述)
    - (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)attrString;
    - (void)insertAttributedString:(NSAttributedString *)attrString atIndex:(NSUInteger)loc;
    - (void)appendAttributedString:(NSAttributedString *)attrString;
    - (void)deleteCharactersInRange:(NSRange)range;
    - (void)setAttributedString:(NSAttributedString *)attrString;
    
    

    3、相关可设置属性对照

    通过API我们可以知道,对于富文本来说添加单个属性和添加属性字典称为其核心方法,就是一个key对应一个Value,只要能了解各种属性所对应效果就可以随意组合,搞出适合各种需求的封装API。

    • NSFontAttributeName :字体字号
      value值:UIFont类型
    • NSParagraphStyleAttributeName : 段落样式
      value值:NSParagraphStyle类型(其属性如下)
      • lineSpacing 行间距(具体用法可查看上面的设置行间距API)
      • paragraphSpacing 段落间距
      • alignment 对齐方式
      • firstLineHeadIndent 指定段落开始的缩进像素
      • headIndent 调整全部文字的缩进像素
    • NSForegroundColorAttributeName 字体颜色
      value值:UIColor类型
    • NSBackgroundColorAttributeName 背景颜色
      value值:UIColor类型
    • NSObliquenessAttributeName 字体粗倾斜
      value值:NSNumber类型
    • NSExpansionAttributeName 字体加粗
      value值:NSNumber类型(比例) 0就是不变 1增加一倍
    • NSKernAttributeName 字间距
      value值:CGFloat类型
    • NSUnderlineStyleAttributeName 下划线
      value值:1或0
    • NSUnderlineColorAttributeName 下划线颜色
      value值:UIColor类型
    • NSStrikethroughStyleAttributeName 删除线
      value值:1或0
    • NSStrikethroughColorAttributeName 删除线颜色
      value值:UIColor类型
    • NSStrokeColorAttributeName 字体颜色
      value值:UIColor类型
    • NSStrokeWidthAttributeName 字体描边
      value值:CGFloat
    • NSLigatureAttributeName 连笔字
      value值:1或0
    • NSShadowAttributeName 阴影
      value值:NSShawdow类型(下面是其属性)
      • shadowOffset 影子与字符串的偏移量
      • shadowBlurRadius 影子的模糊程度
      • shadowColor 影子的颜色
    • NSTextEffectAttributeName 设置文本特殊效果,目前只有图版印刷效果可用
      value值:NSString类型
    • NSAttachmentAttributeName 设置文本附件
      value值:NSTextAttachment类型(没研究过,可自行百度研究)
    • NSLinkAttributeName 链接
      value值:NSURL (preferred) or NSString类型
    • NSBaselineOffsetAttributeName 基准线偏移
      value值:NSNumber类型
    • NSWritingDirectionAttributeName 文字方向 分别代表不同的文字出现方向
      value值:@[@(1),@(2)]
    • NSVerticalGlyphFormAttributeName 水平或者竖直文本 在iOS没卵用,不支持竖版
      value值:1竖直 0水平

    三、示例Demo讲解

    Demo在此,点击可跳转

    • API路径地址如下:
    /YiDing/Class/Helpers/LSCoreToolCenter
    
    

    截图如下:

    • 使用示例路径如下:
    /YiDing/Class/Sections/LSSection/NSMutableAttributedString
    
    

    截图如下

    四、更新

    7.18晚更新:有童鞋想要可以将所有相同的子字符串都可以进行操作,所以添加了一个获取位置数组的方法并封装在内,效果图已经更新,感兴趣的可以去Demo查看。

    相关文章

      网友评论

      • 爱的播放:推荐一款写富文本非常好用的控件:NudeIn,你完全不用去学习这些蛋疼的原生写法,可以像masonry那样写富文本控件
        github地址:https://github.com/hon-key/Nudeln
      • 倔强的小黄瓜:dome放的什么玩意. 看不懂
      • 硅谷小虾米:iOS10.3版本下用富文本做的删除线不显示,有没有好的解决办法
        春暖花已开:@硅谷小虾米 添加一个NSBase属性
      • 堕落小怪兽:写得真好,顶你!!:smiley:
      • ebay_Happy:谢谢大神
      • Ronda:cell中一个label使用富文本,如果才能准确的计算富文本的高度,从而计算cell高度呢
      • Ronda:设置了富文本属性。如何准确的获取富文本的高度呢?
      • 时间戳:作者的demo都是封装到一起的吗,看起来好多
      • 菲了然:建议加一些容错再拿来用会比较好,不过作者本意也是提供一个大致实现方式,赞 :+1:
      • cc_Jumper:这xcode配色超帅,能分享下么 :grin:
        c6f33fbdb985:@彭长城 我觉得文章中这个配色的确很酷 同求
        c6f33fbdb985:@彭长城 dusk自带的更加黑 而且其他颜色也不一样
        王隆帅:@彭长城 就是xcode自带的几种类型中的那个dusk类型,没有特意配:sleepy:
      • Jat: :flushed: 牛逼啊,帅帅~
        王隆帅:@Jat :kissing_heart: :kissing_heart: :kissing_heart: 哈哈
      • 瑞廷:博主,我问下那个如何处理Emoji 表情?我把含有emoji 表情的字符串保存到服务器,返回就成了?????,这个我们客户端要怎么处理
        瑞廷:@王隆帅 谢谢博主啦
        王隆帅:@瑞廷 我没有单独处理系统的emoji,自定义的emoji的话应该是用NSAttachmentAttributeName 插入图片来处理,定义一套对应的规则,要是处理系统的话,我没有实践过,不过我查了查相关资料,你可以看看这里http://www.cnblogs.com/zhanghuanan/p/5576826.html 有用就采纳,没用自己再找找吧 :sweat_smile:
      • f909ef5e3f25:好文章
        王隆帅:@夜猫子丶程序猿 谢谢夸奖:stuck_out_tongue_winking_eye::stuck_out_tongue_winking_eye:
      • 谦言忘语::smile:不错,加油( ¯ᒡ̱¯ )و
        王隆帅:@谦言忘语 谢谢:grin::grin:
      • 来宝:不错
      • Yokihr:感谢你的分享 :+1:
        Yokihr:@王隆帅 好的,感谢 :smiley:
        王隆帅:@Yokihr 已经更新了,感兴趣的话可以看看Demo
      • Yokihr:同时改变字体大小的颜色的方法中,如果某一个词语再一句话当中出现了很多次,只有最后一个词语才会被改变。

        王隆帅:@Yokihr 对的,假如是有相同的是取一个,文中注释已经说了,一般而言假如是不确定内容的想要改变某些特殊字体的颜色需要将API更改,很久之前遇到过这种需求,当时是通过遍历来处理的,等有时间了把这个加上 :blush:
      • 小白e7899:写的很好,如果封装成NSString 的类目感觉更好
        王隆帅:@小白e7899 这个可以按照个人需求的 :stuck_out_tongue_closed_eyes:
      • 拾荒人320:还可以
        王隆帅:@拾荒人320 谢谢鼓励 :yum:
      • JammyT:还以为是图文混排呢,不过这个写的也挺好
        王隆帅:@唐永祥 谢谢鼓励 :blush:
      • 9f94d02340f1:收藏先,总能用得着,
        王隆帅:@JamesYea :stuck_out_tongue:
      • 4f0c5c036d80:赞
        王隆帅:@coderGui :yum:
      • 257f312dccb8:谢谢博主
        王隆帅:@波虎波 :blush:
      • 睡不着的叶:牛逼啊
        王隆帅:@睡不着的叶 夸我我会骄傲的! :stuck_out_tongue:

      本文标题:富文本常用封装(NSAttributedString浅析)

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