iOS 7 引入了一個(gè)非常有用的新功能TextKit窒百,使開發(fā)者可以通過方便的接口去修改文字的樣式和排版,而不需要直接操作復(fù)雜的Core Text。本文將從以下幾個(gè)方面闡述TextKit的使用:
- 什么是TextKit
- TextKit的架構(gòu)
- TextKit的作用
- TextKit中重要的類
- TextKit的具體使用
- 對TextKit的總結(jié)
- 參考的學(xué)習(xí)資料
什么是TextKit
上面那段是引用破船博客里面的解釋的一屋。按照我個(gè)人的理解,TextKit的引入主要是為了解決Core Text復(fù)雜難用袋哼,如果只是從解決大部分功能來說冀墨,使用TextKit的開發(fā)效率會比Core Text高。TextKit 只是 對Core Text進(jìn)行了一些易用性封裝涛贯,解決一些諸如簡單文字排版诽嘉,文字樣式變換等基本需求。如果需要更強(qiáng)的運(yùn)行性能和更強(qiáng)大的靈活性弟翘,TextKit是不能滿足要求的虫腋,這時(shí)候需要Core Text。
TextKit的架構(gòu)
可以從圖中看出稀余,原生的文本控件都是構(gòu)建在TextKit之上的悦冀,使用TextKit進(jìn)行排版和渲染。而UIWebView是構(gòu)建在WebKit上的睛琳,不能使用TextKit功能盒蟆。
TextKit的作用
兩個(gè)最重要的功能:
- 文字排版
- 文字渲染
TextKit中重要的類
如圖所示,TextKit中有四個(gè)重要對象:
- TextView:主要是指UILabel师骗,UITextField历等,UITextView這些文本控件
- TextContainer:對應(yīng)TextKit中的NSTextContainer,主要作用是定義排版區(qū)域辟癌,區(qū)域可以是圓形矩形甚至是不規(guī)則的圖形募闲,也可以定義不能填充的區(qū)域來顯示非文本元素。
- Layout Manager:對應(yīng)TextKit中的NSLayoutManager愿待,主要作用是定義布局方式,使文本內(nèi)容按照一定的布局方式進(jìn)行排版靴患。
- Text Storage:對應(yīng)TextKit中的NSTextStorage仍侥,繼承自NSMutableAttributedString,主要作用是存儲文本字符和文本相關(guān)屬性鸳君。當(dāng)NSTextStorage的屬性發(fā)生變化時(shí)农渊,會通知NSLayoutManager進(jìn)行重新排版。
通常情況下或颊,一個(gè)NSTextStorage 對應(yīng) 一個(gè)NSLayoutManager 對應(yīng) 一個(gè) NSTextContainer砸紊。
當(dāng)文字顯示為多列传于、多頁時(shí),一個(gè)NSLayoutManager 對應(yīng) 多個(gè) NSTextContainer醉顽。
當(dāng)采用不同的排版方式時(shí)沼溜,一個(gè)NSTextStorage對應(yīng)多個(gè)NSLayoutManager。
四個(gè)重要對象的協(xié)同方式(引用自破船的博客游添,一句話解析的非常清楚):
通常由NSLayoutManager從NSTextStorage中讀取出文本數(shù)據(jù)系草,然后根據(jù)一定的排版方式,將文本排版到NSTextContainer中唆涝,再由NSTextContainer結(jié)合UITextView將最終效果顯示出來找都。
TextKit的具體使用
1.只使用NSAttributedString實(shí)現(xiàn)簡單的文字高亮
let attributedString = NSMutableAttributedString(attributedString: textView.attributedText!)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.RedColor(), range: itemRange)
textView.attributedText = attributedString
可以直接使用 NSAttributedString 來設(shè)置文本的樣式,但這個(gè)功能還是比較簡單廊酣,不能設(shè)置布局還有不能處理圖文混排的情況能耻。
2.使用Text Storage實(shí)現(xiàn)文字高亮
// frame
let frame = self.view.bounds
// TextStorage , LayoutManager , TextContainer
let textStorage = NSTextStorage()
let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: frame.size)
layoutManager.addTextContainer(textContainer)
textView = UITextView(frame: frame, textContainer: textContainer)
// textView
self.view.addSubview(textView)
textView.editable = false
textView.selectable = false
let txtString = String.txtString(filename: "lorem", filetype: "txt") // 從文本文件中讀取數(shù)據(jù)
textView.textStorage.replaceCharactersInRange(NSMakeRange(0, 0), withString: txtString)
調(diào)用函數(shù)_highlight() 實(shí)現(xiàn) 前 201 個(gè)字變紅色功能。
/**
語法高亮
*/
private func _highlight() {
textView.textStorage.beginEditing()
// 屬性描述字典
let attributesDict = [NSForegroundColorAttributeName:UIColor.redColor()]
textView.textStorage.setAttributes(attributesDict, range: NSMakeRange(0, 200))
textView.textStorage.endEditing()
}
要對NSTextStorage的屬性進(jìn)行變更前亡驰,要加入
textView.textStorage.beginEditing()
通過這句來開啟textView中textStorage的編輯模式晓猛。
編輯屬性完成后要通過下面這句代碼來結(jié)束編輯模式,并通知NSLayoutManager來更新布局和渲染隐解。
textView.textStorage.endEditing()
3.文本元素與非文本元素混排
TimeIndicatorView 是一個(gè)非文本元素鞍帝,是一個(gè)自定義的UIView子類。
// TimeIndicatorView
timeIndicatorView = TimeIndicatorView(frame: CGRectMake(100,100,100,100))
timeIndicatorView.text = "卡卡卡卡卡卡卡卡卡卡"
textView.addSubview(timeIndicatorView)
TimeIndicatorView的形狀是圓形煞茫,所以要對textContainer中的exclusionPaths設(shè)置成相應(yīng)的圓形路徑帕涌,這圓形內(nèi)不進(jìn)行文字的排版和渲染,也就是說排除這個(gè)圓形的填充區(qū)域续徽。
/**
遮蓋范圍
*/
private func _updateExclusionPaths() {
var circleFrame = self.textView.convertRect(timeIndicatorView.bounds, fromView: timeIndicatorView) // 坐標(biāo)轉(zhuǎn)換
circleFrame.origin.x = circleFrame.origin.x - textView.textContainerInset.left
circleFrame.origin.y = circleFrame.origin.y - textView.textContainerInset.top
let circlePath = UIBezierPath(roundedRect: circleFrame, cornerRadius: timeIndicatorView.radius())
textView.textContainer.exclusionPaths = [circlePath]
}
效果圖:
對TextKit的總結(jié)
上面的例子這是實(shí)現(xiàn)了一些很簡單的功能蚓曼,通過這些簡單功能來演示一下TextKit在文本排版和文本渲染的強(qiáng)大功能。這里是用Swift寫的TextKit演示的demo:TextKitDemo钦扭。這里沒有對NSTextContainer纫版,NSTextStorage,NSLayoutManager這三個(gè)進(jìn)行定制客情,事實(shí)上可以通過對這三個(gè)的定制來實(shí)現(xiàn)非常強(qiáng)大的排版和渲染功能其弊,由于本人對TextKit的理解還比較淺,所以這里就不進(jìn)行深究了膀斋。
參考的學(xué)習(xí)資料
Text Kit Tutorial: Getting Started
Using Text Kit to Manage Text in Your iOS Apps
TextKit學(xué)習(xí)(三)NSTextStorage梭伐,NSLayoutManager,NSTextContainer和UITextView
iOS 7中文字排版和渲染引擎——Text Kit
iOS 7 教程:淺析Text Kit
TextKit