出现在应用界面上的文本是NSString
与NSAttributedString
(字符与段落)。
为了让NSString
与NSAttributedString
出现在界面上,可以将其绘制到图形上下文中,或者交给界面对象(UILabel
、UITextField
、UITextView
,它们都有属性attributedText
)来绘制。
在底层,所有的文本绘制都是通过Core Text
(C样式的API)执行,Text Kit
是建立在Core Text之上的中间层技术。
Text Kit
包含一小组类,负责绘制文本
UITextView
可以直接获取底层的Text Kit引擎,它有如下与Text Kit有关的属性:
TextContainer
:text view的文本容器,NSTextContainer实例。UITextView的指定初始化器是init(frame:textContainer:)
,其中textContainer:
可以是nil
来得到默认的文本容器,或者提供自定义的文本容器。textContainerInset
:文本容器的边距,改变这个值会立即改变边距,致使文本布局改变。layoutManager
:text view的布局管理器,NSLayoutManager
实例textStorage
:text view的文本存储,NSTextStorage
实例使用自定义的文本容器初始化text view时,相当于传递整个Text Kit的栈的实例:text container,layout manager,text storage。最简单、最常见的情况是:text storage持有layout manager,而layout manager持有text container,这样就构成了栈。
let r = CGRectMake(100, 100, 100, 100)
let lm = NSLayoutManager()
let ts = NSTextStorage()
ts.addLayoutManager(lm)
let tc = NSTextContainer(size: CGSizeMake(r.width,r.height))
lm.addTextContainer(tc)
self.textView = UITextView(frame: r, textContainer: tc)
Text Kit三个主要的类:
NSTextStorage
:NSMutableAttributedString
的子类,它包含底层的文本,它持有一个或多个布局管理器,当文本改变时,就会通知布局管理器。NSTextContainer
:它被布局管理器持有,帮助布局管理器定义文本布局的区域。以三种方式来实现:
<1>Size
:文本容器的左上角是文本布局坐标系统的起点,文本会在文本容器的矩形框内布局
<2>Exclusion paths
:exclusionPaths
属性包含UIBezierPath
对象,路径内不绘制文本。
<3>Subclassing
:通过重写lineFragmentRectForProposedRect:atIndex:writing- Direction:remainingRect:
,你可以将每一块的文本绘制在任何地方。
NSLayoutManager
:这是主要的文本绘制类!它持有一个或多个文本容器,而它被text storage持有。它将text storage的文本绘制到text container(s)定义的边界中。
NSTextStorage 相当于模型层,用于管理文本的底层存储,以及如何定义文本显示的样式。
NSTextContainer
有属性size
,文本会绘制到该区域,默认,text view的text container的宽度等于text view的宽度,而高度是无限的。
它也有与
属性,当你改变text view的textContainerInset
时,它会调整text container的尺寸来搭配。可以通过text container的lineFragmentPadding
来产生侧边距,默认是5.
你可以对text container应用exclusion paths,此外,还可以子类化NSTextContainer
来调整文本所放置的矩形区域,重写方法func lineFragmentRectForProposedRect(
proposedRect: CGRect, atIndex characterIndex: Int,
writingDirection baseWritingDirection: NSWritingDirection,
remainingRect: UnsafeMutablePointer
默认的Text Kit栈是:一个text storage,持有一个layout manager,而该layout manager持有一个text container。但是,一个text storage可以持有多个layout manager,而一个layoutmanager可以持有多个text container。
一.一个layout manager持有多个text container
二.一个text storage持有多个layout manager,则每个layout manager布局相同的文本
UITextView是iOS中唯一内置的可以获取Text Kit栈的类,但是你可以在任何图形上下文中使用Text Kit来绘制。你应当总要调用drawBackgroundForGlyphRange:atPoint:
和drawGlyphsForGlyphRange:atPoint:
,其中,point:
参数是text container在当前图形上下文中的起点。