Text Kit 富文本實(shí)現(xiàn)

1. Text Kit基礎(chǔ) ?

? ? ? ? Text Kit最主要的作用 是為程序提供文字排版和渲染的功能。通過Text Kit可以對(duì)文字進(jìn)行存儲(chǔ)、布局,以更加精 的排版方式來顯示文本內(nèi)容。Text Kit屬于UIKit框架,其中包 了一些文字排版的相關(guān)類和協(xié) 。?

? ? ? ? 在iOS 7之前沒有Text Kit。文本控件,如:UILabel、UITextField和UITextView是基于String Drawing和WebKit構(gòu)建的。其中String Drawing與Core Graphics接通信。因此在iOS 7之前文本控件也可以實(shí)現(xiàn)多種樣式的文字排版,但是事實(shí)上是通過WebKit實(shí)現(xiàn)的。WebKit是一種瀏覽器內(nèi)核技術(shù),使用它進(jìn)行文字渲染會(huì)? ? 較多的內(nèi)存,對(duì)應(yīng)用的性能有一定的? 。

? ? ? 在iOS7之后,UILabel、UITextfField和UITextView構(gòu)建于TextKit之上,Text Kit是基于Core Text構(gòu)建的, 通過Core Text與Core Graphics進(jìn)行交 。

1.1 Text Kit中的核心類 ?

我們?cè)谑褂肨ext Kit時(shí),會(huì) 及如下核心類。

1.? `NSTextContainer。定 了文本可以排版的區(qū) 。 認(rèn)情況下是矩形區(qū) ,如果是其它形狀的區(qū)域,需要通過子類化NSTextContainer來創(chuàng)建。`

2. `NSLayoutManager。該類負(fù)責(zé)對(duì)文字進(jìn)行編 排版處理,將存儲(chǔ)在NSTextStorage中的數(shù)據(jù)轉(zhuǎn)換為可以在視圖控件中顯示的文本內(nèi)容,并把字編碼映射到到對(duì)應(yīng)的字形上,然后將字形排版到NSTextContainer定義的區(qū)域中。`

3. `NSTextStorage。主要用來存儲(chǔ)文本的字 和相關(guān)屬性`

4. `NSAttributedString。 持渲染不同風(fēng)格的文本。`

5. `NSMutableAttributedString??勺冾?的NSAttributedString,是NSAttributedString的子類`

NSLayoutManager對(duì)象從NSTextStorage對(duì)象中取得文本內(nèi)容, 進(jìn)行排版,然后把排版之后的文本放到NSTextContainer對(duì)象指定的區(qū) 上。最后 由一個(gè)文本控件從 NSTextContainer中取出內(nèi)容顯示到屏幕中。


1.2 凸印效果的實(shí)現(xiàn)

直接上代碼

//創(chuàng)建一個(gè)矩形區(qū),這個(gè)區(qū)是通過CGRectInset函數(shù)創(chuàng)建的,這個(gè)函數(shù)能指定一個(gè)中

//心點(diǎn),后面的兩個(gè)參數(shù)著self.view.bounds區(qū)域向內(nèi)內(nèi)進(jìn)量。這樣可以使得文字部分不會(huì)太靠近視圖的邊界。

CGRecttextViewRect =CGRectInset(self.view.bounds,10.0,20.0);

//主要用來存儲(chǔ)文本的字和相關(guān)屬性

NSTextStorage* textStorage = [[NSTextStoragealloc]initWithString:_textView.text];

//該類負(fù)責(zé)對(duì)文字進(jìn)行編排版處理,將存儲(chǔ)在NSTextStorage中的數(shù)據(jù)轉(zhuǎn)換為可以在視圖控件中顯示的文本內(nèi)容

NSLayoutManager* layoutManager = [[NSLayoutManageralloc]init];

[textStorageaddLayoutManager:layoutManager];

//定義了文本可以排版的區(qū)

_textContainer= [[NSTextContaineralloc]initWithSize:textViewRect.size];

/**

*NSLayoutManager對(duì)象從NSTextStorage對(duì)象中取得文本內(nèi)容,進(jìn)行排版,

*然后把排版之后的文本放到NSTextContainer對(duì)象指定的區(qū)域上。

*最后由一個(gè)文本控件從NSTextContainer中取出內(nèi)容顯示到屏幕中。

*/

[layoutManageraddTextContainer:_textContainer];

[_textViewremoveFromSuperview];

_textView= [[UITextViewalloc]initWithFrame:textViewRect

textContainer:_textContainer];

_textView.textColor= [UIColoryellowColor];

_textView.editable=NO;

[self.viewaddSubview:_textView];

//設(shè)置凸印效果

[textStoragebeginEditing];

NSDictionary*attrsDic =@{NSTextEffectAttributeName:NSTextEffectLetterpressStyle};

NSMutableAttributedString*attrStr = [[NSMutableAttributedStringalloc]

initWithString:_textView.text

attributes:attrsDic];

[textStoragesetAttributedString:attrStr];

[self markWord:@"you"inTextStorage:textStorage];

[self markWord:@"I"inTextStorage:textStorage];

[self markWord:@"言"inTextStorage:textStorage];

[textStorageend Editing];

標(biāo)識(shí)制定文字

- (void) markWord:(NSString*)word inTextStorage:(NSTextStorage*)textStorage{

NSRegularExpression*regex = [NSRegularExpressionregularExpressionWithPattern:word

options:0

error:nil];

NSArray*matches = [regexmatchesInString:_textView.text

options:0

range:NSMakeRange(0,[_textView.textlength])];

for(NSTextCheckingResult*matchinmatches) {

NSRangematchRange = [matchrange];

[textStorageaddAttribute:NSForegroundColorAttributeName

value:[UIColorredColor]

range:matchRange];

}

效果圖:


富文本

1.3 圖文混排

Text Kit通過環(huán)繞路徑(exclusion paths)將文字按照指定的路徑環(huán)繞在圖片等視圖對(duì)象的周圍

// 在上面代碼基礎(chǔ)上,添加一個(gè)UIImageView

// 指定NSTextContainer環(huán)繞路徑實(shí)現(xiàn)圖文混排

//設(shè)置環(huán)繞路徑,可以指定多個(gè)

_textView.textContainer.exclusionPaths=@[[selftranslatedBezierPath]];

取得UIImageView的貝塞爾曲線

-(UIBezierPath*) translatedBezierPath{

//將imageView相對(duì)于View的坐標(biāo)轉(zhuǎn)換為相對(duì)于textView的坐標(biāo)

CGRectimageRect = [self.textViewconvertRect:_imageView.frame

fromView:self.view];

UIBezierPath*newPath = [UIBezierPathbezierPathWithRect:imageRect];

return newPath;

}

效果圖


圖文混排


1.4 動(dòng)態(tài)字體

注冊(cè)UIContentSizeCategoryDidChangeNotification通知,實(shí)現(xiàn)動(dòng)態(tài)字體功能

[[NSNotificationCenterdefaultCenter]addObserver:self

selector:@selector(preferredContentSizeChanged:)

name:UIContentSizeCategoryDidChangeNotification

object:nil];

#pragma mark --監(jiān)聽字體變化

- (void)preferredContentSizeChanged:(NSNotification*)notification{

// do something

}

圖文混排cpu、memory使用非常高,怎么優(yōu)化?


demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容