????????在iOS開發(fā)中,經(jīng)常遇到富文本內(nèi)容的展示,雖然系統(tǒng)的NSAttributedString功能已經(jīng)比較完善,但是比較缺乏定制化的內(nèi)容,如果想自由度更高的顯示富文本,可以嘗試YYText這個框架。下面會對框架的使用進行簡單的介紹。
常用的富文本屬性
1.背景色塊:系統(tǒng)的AttributedString雖然也有背景色的屬性設置,但是有時候需要色塊加上圓角。就需要用到YYTextBorder

NSMutableAttributedString* str = [[NSMutableAttributedString alloc] initWithString:XX];? ? //創(chuàng)建內(nèi)容富文本
[str?yy_insertString:@"?" atIndex:0];
[str?yy_appendString:@" "];? ? ? ? ? ? //前后的間距
YYTextBorder * border = [YYTextBorder borderWithFillColor:XXColor cornerRadius:XX];? ? //創(chuàng)建背景色(顏色與圓角)
border.insets=UIEdgeInsetsMake(0,0,0,0);? ? ? ? //背景色的偏移量
[str?setYy_textBackgroundBorder:border];
2.圖文混排:也就是字符串中添加圖片,就需要用到YYTextAttachment這個類。
先引用一下作者的簡單介紹?
YYTextAttachment是NSAttributedString的類簇,它的實例作為富文本key屬性YYTextAttachmentAttributeName的value。當富文本包含YYTextAttachment時,它會采用文本規(guī)則展示。比如,attachment的內(nèi)容是UIImage時,它會被繪制為CGContext;attachment的內(nèi)容是UIView或CALayer時,它會被加入到text container的view層或layer層上。
簡單用法
UIImage *image = [UIImage imageNamed:@"XX"];? ? //要顯示的圖片
NSMutableAttributedString *attachText = [NSMutableAttributedString yy_attachmentStringWithContent:image contentMode:UIViewContentModeCenter attachmentSize:CGSizeMake(10, 10) alignToFont:[UIFont boldSystemFontOfSize:16] alignment:YYTextVerticalAlignmentCenter];? ? //content:內(nèi)容? size:圖片尺寸 alignToFont:字符串內(nèi)字體的格式??
[result appendAttributedString:attachText];? ? ?//把圖片加入字符串中
字符串的屬性還有很多,比如高亮YYTextHightlight,邊框YYTextBorder,下劃線YYTextBorder 等等等等??梢哉f是非常豐富了。
YYLabel的使用
????????有了富文本的內(nèi)容,現(xiàn)在就需要一個顯示內(nèi)容的容器,YYKit提供了文本框YYLabel,使用也很方便,下面會舉例幾個常用的設置。
1.YYTextContainer
顯示text的容器,初始化方法分為
矩形: + (instancetype)containerWithSize:(CGSize)size;
和非矩形:+ (instancetype)containerWithPath:(nullableUIBezierPath*)path;
也有一些常見的屬性可以設置,如行數(shù)?maximumNumberOfRows? 大小 size?
?2.YYTextLayout
? ? ? ? ? ?用來控制text的布局,大神的分析如下
? ? ? ? ? ? ? ?這個真的是核心內(nèi)容了,這個文件一共3300多行的代碼,從代碼量上就能看出它的地位。這個類中存儲著text的layout結果,所有的property都是readonly的。實現(xiàn)的接口有:
? ? ? ? ? ? ? ?1、通過一些類方法初始化的方法(YYTextContainer、CGSize和text)
? ? ? ? ? ? ? ?2、layout之后的attributes,都是只讀的
? ? ? ? ? ? ? ?3、從layout中讀取信息(位置、range等等)
? ? ? ? ? ? ? ?4、繪制text layout
? ? ? ? ? ? ? ?這個類主要是使用上面講過的所有的數(shù)據(jù)來繪制text,這部分的代碼還是需要一點一點的去讀的,如果是新手每一行都會有收獲(比如說我),如果是老司機就沒有必要一行行的讀了,了解他的解題思路和解決這個問題的辦法就可以。下面說一下生成layout的那個500行代碼的情況,就按照代碼的順序從上往下大概的說明一下干了什么。
? ? ? ? ? ? ? ? ?????? ? 1)、初始化一系列使用到的變量
? ? ? ? ? ? ? ?????? ? ? 2)、安全判斷,text和container
? ? ? ? ? ? ? ?????? ? ? 3)、判斷是否需要修復emoji的bug(iOS8.3中)
? ? ? ? ? ? ? ?????? ? ? 4)、判斷是否設置了path屬性和exclusionPaths數(shù)組,做相應的計算拿到cgpath,如果cgpath為空則goto fail 返回nil(如果設置了path,size和insets就沒有用了)
? ? ? ? ? ? ? ?????? ? ? 5)、判斷是不是奇偶填充,判斷pathWidth是否為0,判斷是否是垂直展示
? ? ? ? ? ? ? ?????? ? ? 6)、使用text創(chuàng)建CTFramesetterRef,創(chuàng)建失敗goto fail
? ? ? ? ? ? ? ?????? ? ? 7)、使用上一步中創(chuàng)建的frameSetter創(chuàng)建CTFrameRef
? ? ? ? ? ? ? ?????? ? ? 8)、從CTFrameRef的對象中獲得每一行、ctRun數(shù)組,計算每一行的frame,判斷是否實現(xiàn)了linePositionModifier這個協(xié)議,有的話調(diào)用協(xié)議方法。
? ? ? ? ? ? ? ?????? ? ? 9)、計算bounding size
? ? ? ? ? ? ? ? ?????? ? 10)、判斷是否需要truncation,和按那種方式處理
? ? ? ? ? ? ? ? ?????? ? 11)、判斷是否垂直布局text,需要的話,旋轉布局
? ? ? ? ? ? ? ? ?????? ? 12)、判斷得到的visibleRange長度,有效的話遍歷text中的attributes,配置對應的layout屬性
? ? ? ? ? ? ? ? ?????? ? 13)、配置layout中的attachments
? ? ? ? ? ? ? ? ?????? ? 14)、配置結束,返回layout
? ? ? ? ? ? ??????? 繪制時就是根據(jù)layout中的配置情況繪制相應的特征,這段代碼在此就不做分析了。
我這邊只是用來確定YYLabel的布局,用法如下
YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:str];
self.label.size= layout.textBoundingSize;
self.titleLabel.textLayout= layout;
????????以上就是YYText的一些簡單用法,后續(xù)如果有新的需求,會更仔細的研究下這個框架更高級的用法,很多功能其實還沒有用到,但是已經(jīng)體會到了代碼開源的好處。
????????其實我們在開發(fā)中遇到的大部門復雜功能,在github中多多少少都能找到類似的框架去參考,很多情況下我們是不需要造輪子的。但是當你找到一個好輪子時,一定要多多理解實現(xiàn)原理,第一能讓你后續(xù)對框架的改造更容易,第二也是讓我們?nèi)W習,感受大神的思想,開闊自己的思維,總之是好處多多。而自己寫代碼時,對一些常用功能,也要做好解耦和封裝,也要照著開源的規(guī)范要求自己,這樣后續(xù)的開發(fā)中是非常提高效率的。