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

1. Text Kit基礎(chǔ) ?

? ? ? ? Text Kit最主要的作用 是為程序提供文字排版和渲染的功能。通過Text Kit可以對文字進行存儲垢村、布局,以更加精 的排版方式來顯示文本內(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之前文本控件也可以實現(xiàn)多種樣式的文字排版,但是事實上是通過WebKit實現(xiàn)的炊甲。WebKit是一種瀏覽器內(nèi)核技術(shù)泥彤,使用它進行文字渲染會? ? 較多的內(nèi)存,對應(yīng)用的性能有一定的? 卿啡。

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

1.1 Text Kit中的核心類 ?

我們在使用Text Kit時滞伟,會 及如下核心類揭鳞。

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

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

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

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

5. `NSMutableAttributedString◎鹬可變類 的NSAttributedString狞膘,是NSAttributedString的子類`

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


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

直接上代碼

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

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

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

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

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

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

NSLayoutManager* layoutManager = [[NSLayoutManageralloc]init];

[textStorageaddLayoutManager:layoutManager];

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

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

/**

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

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

*最后由一個文本控件從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];

標識制定文字

- (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)繞在圖片等視圖對象的周圍

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

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

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

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

取得UIImageView的貝塞爾曲線

-(UIBezierPath*) translatedBezierPath{

//將imageView相對于View的坐標轉(zhuǎn)換為相對于textView的坐標

CGRectimageRect = [self.textViewconvertRect:_imageView.frame

fromView:self.view];

UIBezierPath*newPath = [UIBezierPathbezierPathWithRect:imageRect];

return newPath;

}

效果圖


圖文混排


1.4 動態(tài)字體

注冊UIContentSizeCategoryDidChangeNotification通知,實現(xiàn)動態(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)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喂窟,隨后出現(xiàn)的幾起案子测暗,更是在濱河造成了極大的恐慌,老刑警劉巖磨澡,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碗啄,死亡現(xiàn)場離奇詭異,居然都是意外死亡稳摄,警方通過查閱死者的電腦和手機稚字,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胆描,你說我怎么就攤上這事瘫想。” “怎么了昌讲?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵国夜,是天一觀的道長。 經(jīng)常有香客問我剧蚣,道長支竹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任鸠按,我火速辦了婚禮礼搁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘目尖。我一直安慰自己馒吴,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布瑟曲。 她就那樣靜靜地躺著饮戳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪洞拨。 梳的紋絲不亂的頭發(fā)上扯罐,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天,我揣著相機與錄音烦衣,去河邊找鬼歹河。 笑死,一個胖子當(dāng)著我的面吹牛花吟,可吹牛的內(nèi)容都是我干的秸歧。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼衅澈,長吁一口氣:“原來是場噩夢啊……” “哼键菱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起今布,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤经备,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后部默,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弄喘,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年甩牺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片累奈。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡贬派,死狀恐怖急但,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搞乏,我是刑警寧澤波桩,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站请敦,受9級特大地震影響镐躲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜侍筛,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一萤皂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匣椰,春花似錦裆熙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佳镜,卻和暖如春僚稿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蟀伸。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工蚀同, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人望蜡。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓唤崭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脖律。 傳聞我的和親對象是個殘疾皇子谢肾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內(nèi)容