YYText之圖文混排
1.圖文混排的原理?
我覺(jué)得,查看代碼前彬向,最重要的一件事是知道圖文混排到底是怎么實(shí)現(xiàn)的。
核心思想:生成富文本時(shí)把攻冷,一張圖片先用一個(gè)占位符代替娃胆。實(shí)際渲染時(shí),圖片占位符的渲染處理會(huì)更多一些等曼。
根據(jù)這個(gè)原理里烦,我們開(kāi)始深入的學(xué)習(xí)。本文Demo基于YYKitExample涉兽。
2.YYTextAttachmentExample
我們先看YYTextAttachmentExample.m
中的代碼實(shí)現(xiàn)招驴。self.view
上有3個(gè)富文本,并且末尾都帶了圖片枷畏。我們可以看出别厘,設(shè)置富文本的核心方法如下,深入看看其中做了什么拥诡。
+ (NSMutableAttributedString *)attachmentStringWithContent:(id)content
contentMode:(UIViewContentMode)contentMode
attachmentSize:(CGSize)attachmentSize
alignToFont:(UIFont *)font
alignment:(YYTextVerticalAlignment)alignment;
結(jié)合代碼運(yùn)行流程触趴,我們分為以下幾個(gè)部分:
2.1 生成NSMutableAttributedString實(shí)例
初始化時(shí)提供了一個(gè)占位符@"\uFFFC"
氮发,用于代替圖片信息。
2.2 YYTextAttachment
說(shuō)到圖文混排冗懦,必然會(huì)用到NSTextAttachment
爽冕,它是NSAttributedString
的類簇,設(shè)置富文本時(shí)對(duì)應(yīng)的key是NSAttachmentAttributeName
披蕉。簡(jiǎn)而言之颈畸,我們給一個(gè)NSAttributedString
實(shí)例添加圖片時(shí),就是將image實(shí)例
作為以上key的value没讲。YYText
自身實(shí)現(xiàn)了一個(gè)YYTextAttachment
眯娱,作者是這么介紹的:
YYTextAttachment
是NSAttributedString
的類簇,它的實(shí)例作為富文本key屬性YYTextAttachmentAttributeName
的value爬凑。當(dāng)富文本包含YYTextAttachment
時(shí)徙缴,它會(huì)采用文本規(guī)則展示。比如嘁信,attachment
的內(nèi)容是UIImage
時(shí)于样,它會(huì)被繪制為CGContext
;attachment
的內(nèi)容是UIView
或CALayer
時(shí)潘靖,它會(huì)被加入到text container
的view
層或layer
層上穿剖。
2.3 YYTextRunDelegate
在這之前我們先要知道,NSAttributedString
相比于NSString
多了很多attribute
的概念卦溢,比如下劃線携御、背景色等。每個(gè)字符都有一個(gè)字符區(qū)域既绕,渲染每個(gè)字符多種多樣的attributes
都是在這個(gè)區(qū)域的基礎(chǔ)上的。轉(zhuǎn)換成代碼是什么意思呢涮坐?CoreText
的為我們提供了這個(gè)體系:
NSAttributedString
初始化后會(huì)生成CTFramesetter
凄贩,CTFramesetter
根據(jù)不同的CGPath生成對(duì)應(yīng)的CTFrame
,一個(gè)CTFrame
由多行CTLine
組成袱讹,一個(gè)CTLine
會(huì)包含多個(gè)CTRun
(字形繪制的最小單元)疲扎。
結(jié)合之前說(shuō)的繪制的核心思想,可以這么理解:一行帶有文字和圖片的富文本捷雕,包含若干個(gè)CTRun
繪制單元椒丧,圖片的繪制單元相對(duì)特殊一些。為什么呢救巷?因?yàn)?code>CoreText并不能直接將一個(gè)圖片轉(zhuǎn)換為CTRun來(lái)繪制壶熏,所以它先用占位符預(yù)留空間,而真正的圖片繪制是交給CoreGraphics
完成的浦译。
問(wèn)題又來(lái)了棒假,CoreGraphics
是如何拿到這些繪圖信息(descent溯职、ascent、width等)呢帽哑?到這終于引出了CTRunDelegate
谜酒。我們?yōu)楦晃谋镜?code>kCTRunDelegateAttributeName屬性賦值一個(gè)CTRunDelegate
實(shí)例,CoreText
可以根據(jù)它拿到它內(nèi)部的屬性,如descent、ascent晓避、width等浊吏。
2.4 小結(jié)
通過(guò)以上3個(gè)步驟,一個(gè)富文本就生成了寓辱。其中涉及到了CoreText
的許多類,尤其是NSTextAttachment
和CTRunDelegate
。還有碉输,富文本的文本結(jié)構(gòu)。詳細(xì)內(nèi)容亭珍,推薦《Text Programming Guide for iOS》