YYText之圖文混排
1.圖文混排的原理?
我覺得,查看代碼前,最重要的一件事是知道圖文混排到底是怎么實現的。
核心思想:生成富文本時把,一張圖片先用一個占位符代替。實際渲染時,圖片占位符的渲染處理會更多一些。
根據這個原理,我們開始深入的學習。本文Demo基于YYKitExample。
2.YYTextAttachmentExample
我們先看YYTextAttachmentExample.m
中的代碼實現。self.view
上有3個富文本,并且末尾都帶了圖片。我們可以看出,設置富文本的核心方法如下,深入看看其中做了什么。
+ (NSMutableAttributedString *)attachmentStringWithContent:(id)content
contentMode:(UIViewContentMode)contentMode
attachmentSize:(CGSize)attachmentSize
alignToFont:(UIFont *)font
alignment:(YYTextVerticalAlignment)alignment;
結合代碼運行流程,我們分為以下幾個部分:
2.1 生成NSMutableAttributedString實例
初始化時提供了一個占位符@"\uFFFC"
,用于代替圖片信息。
2.2 YYTextAttachment
說到圖文混排,必然會用到NSTextAttachment
,它是NSAttributedString
的類簇,設置富文本時對應的key是NSAttachmentAttributeName
。簡而言之,我們給一個NSAttributedString
實例添加圖片時,就是將image實例
作為以上key的value。YYText
自身實現了一個YYTextAttachment
,作者是這么介紹的:
YYTextAttachment
是NSAttributedString
的類簇,它的實例作為富文本key屬性YYTextAttachmentAttributeName
的value。當富文本包含YYTextAttachment
時,它會采用文本規則展示。比如,attachment
的內容是UIImage
時,它會被繪制為CGContext
;attachment
的內容是UIView
或CALayer
時,它會被加入到text container
的view
層或layer
層上。
2.3 YYTextRunDelegate
在這之前我們先要知道,NSAttributedString
相比于NSString
多了很多attribute
的概念,比如下劃線、背景色等。每個字符都有一個字符區域,渲染每個字符多種多樣的attributes
都是在這個區域的基礎上的。轉換成代碼是什么意思呢?CoreText
的為我們提供了這個體系:
NSAttributedString
初始化后會生成CTFramesetter
,CTFramesetter
根據不同的CGPath生成對應的CTFrame
,一個CTFrame
由多行CTLine
組成,一個CTLine
會包含多個CTRun
(字形繪制的最小單元)。
結合之前說的繪制的核心思想,可以這么理解:一行帶有文字和圖片的富文本,包含若干個CTRun
繪制單元,圖片的繪制單元相對特殊一些。為什么呢?因為CoreText
并不能直接將一個圖片轉換為CTRun來繪制,所以它先用占位符預留空間,而真正的圖片繪制是交給CoreGraphics
完成的。
問題又來了,CoreGraphics
是如何拿到這些繪圖信息(descent、ascent、width等)呢?到這終于引出了CTRunDelegate
。我們為富文本的kCTRunDelegateAttributeName
屬性賦值一個CTRunDelegate
實例,CoreText
可以根據它拿到它內部的屬性,如descent、ascent、width等。
2.4 小結
通過以上3個步驟,一個富文本就生成了。其中涉及到了CoreText
的許多類,尤其是NSTextAttachment
和CTRunDelegate
。還有,富文本的文本結構。詳細內容,推薦《Text Programming Guide for iOS》