[iOS] 利用 NSAttributedString 进行富文本处理

Posted wwbb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[iOS] 利用 NSAttributedString 进行富文本处理相关的知识,希望对你有一定的参考价值。

许多时候我们需要以各种灵活的形式展现文本信息,即富文本。普通的 text 属性显然无法满足要求,这时我们需要利用 Foundation 中的 NSAttributedString——属性字符串进行设置。拥有文本显示功能(text 属性)的 UI 控件也都拥有 attributedText 属性。

常用方法

和 NSString 及 Foundation 框架其它集合一样,NSAttributedString 也拥有一个子类 NSMutableAttributedString 执行修改方面的操作。

 

 

基本的使用流程是初始化一个 NSMutableAttributedString 对象并指定源文本,然后进行属性设置操作,最后赋值给目标控件的 attributedText 属性。

注意到方法介绍中 attribute(属性)和 range(范围)出现频次相当高,实际上这也是 NSAttributedString 的核心内容——在正确的范围设置合适的属性。下面我们就从这两方面进行介绍。

attribute (属性)

UIKit 中声明了一个 NSAttributedString 的分类,定义了可用的属性类型。一些普通文本属性和方法也会用到这些属性。

 

 

需要注意的是文本显示控件中的 attributedText 属性并不会继承 text 属性中的文本设置,初学者往往会遗漏掉经常在普通文本中设置的诸如字体大小和颜色等基本属性,造成显示效果失常。

这里特别介绍一下 NSTextAttachment(文本附件),对应 NSAttachmentAttributeName 类型。NSTextAttachment 对象中的 image 属性可以为属性文本提供图片,bounds 属性设置图片的尺寸(通常利用 UIFont 的 lineHight 属性使之与文本等高)。

如果用 NSAttachmentAttributeName 类型对象的方式以属性插入附件,会有一个问题是不好确认 range。所幸 NSTextAttachment 类中提供了一个 NSAttributedString 的分类初始化方法:

 

 

因此对于 NSTextAttachment 对象,最好是以设置为 NSAttributedString 对象的方式插入。

range(范围)

对于一些内容固定的简单文本,我们可以直接设置出固定的 range,但如果是内容未知属性设置需求复杂的不定长文本(比如微博),问题就不小了。为了获得目标 range,我们需要通过 NSRegularExpression 类利用正则表达式进行过滤检索。

正则表达式

这部分内容太广了,可以搜索教程自学,比如这里。花上半天一天的时间,做到熟悉语法和关键词,能自己进行一些中低难度的检索并且看懂大部分表达式就差不多了。

NSRegularExpression

首先通过正则表达式设置过滤规则字符串:

 

 

初始化为 NSRegularExpression 对象。初始化方法:

 

 

搜索目标字符串获得匹配字段:

 

 

RegEx Categories

GitHub 上的一个高星项目(这是地址),对 NSRegularExpression 进行了格式上的简化和功能上的便利性扩展,推荐使用。

综合实例

将下面这条文本信息按微博样式显示:

 

 

难点:表情替换。由于替换表情和原字段的长度不同,如果直接替换,文本长度改变,而后面的匹配字段的 range 是按原文本计算的,这样会造成显示错位。

解决方法是根据过滤条件按顺序获得所有(包括不匹配)字段的 range 数组,然后再拼接出目标属性文本。很可惜,NSRegularExpression 和 RegEx Categories 都没有提供合适的分离方法,需要我们自己实现。

自定义 NSRegularExpression 分类文件:

 

 

主文件:

 

以上是关于[iOS] 利用 NSAttributedString 进行富文本处理的主要内容,如果未能解决你的问题,请参考以下文章

[iOS] 利用 NSAttributedString 进行富文本处理

iOS利用视频做起始页

[PHP]利用XAMPP搭建本地服务器, 然后利用iOS客户端上传数据到本地服务器中(四. iOS端代码实现)

利用github.io写博客

利用github.io写博客

利用缓冲流读取跟写入