利用 NSAttributedString 進行富文本處理


原文出自  http://blog.qiji.tech/archives/8335#RegEx_Categories

 

[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 分類文件:

 

 

主文件:

 

 

顯示效果:

NSAttributedString 實例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM