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
}