TextKit官方文档阅读笔记

iOS中文本控件的底层是TextKit,它能够精细地排版与布局文本
TextKit是对CoreText的封装(如下图),所以有同样的性能


image.png

image.png

在TextKit中,NSTextStorage存储了显示在TextViews中的string,文本的布局是由NSLayoutManager来处理的,文本的布局区域由于NSTextContainer定义

NSTextContainer:

NSTextContainer定义了一个区域,文本在该区域内布局,一般是矩形,也可以创建NSTextContainer的子类来自定义为其他形状

NSTextStorage:

NSTextStorage是NSMutableAttributedString的子类 ,存储着string和Attribute,你可以把它看做TextKit的数据库,另外它还管理者一组NSLayoutManager对象,因为当文本改变的时候需要通知NSLayoutManager

NSLayoutManager:

NSLayoutManager管理NSTextStorage和NSTextContainer,它负责把NSTextStorage中的文本显示出来,把字符转为字形,管理布局

2.Text Attributes

Text Kit可以处理三种文本属性:字符属性(Character Attributes),段落属性(Paragraph Attributes)和文档属性(Document Attributes)。

2.1字符属性(Character Attributes)

addAttribute:value:range://你可以用该方法给文本添加属性
drawGlyphsForGlyphRange:atPoint//如果需要自定义属性,就需要实现NSLayoutManager子类并且重写该方法

2.1字符属性(Paragraph Attributes)

很简单: 使用NSParagraphStyle添加段落属性

3.1文档属性(Document Attributes)

initWithRTF:documentAttributes://文本系统没有其他的机制存储文档属性,就提供了该方法初始化的时候设置

改变Text Storage

//一共3步
1.`[beginEditing]`
2.改变文本属性,比如`setAttributes:range:`,当执行完第一步后,
//每当你改变文本属性的时候,
//text storage对象都会调用edited:range:changeInLength:方法来跟踪修改
3.`[endEditing]`//这时候text storage会
//调用代理方法[textStorage:willProcessEditing:range:changeInLength:],
//然后调用它自己的[processEditing](fixing attributes within the recorded range of changed characters)
//再调用代理[textStorage:didProcessEditing:range:changeInLength:]给代理一个机会验证或改变文本属性
//最后发送[processEditingForTextStorage:edited:range:changeInLength:invalidatedRange:]给所有的layout manager,layout managers用这些信息重新计算字形的位置,重新显示

3.Laying out Text

NSLayoutManager是TextKit的中央控制系统,在MVC中,NSLayoutManager就是C, NSTextStorage是M, NSTextContainer其实也是M,因为它存储了视图显示的区域, UITextView是V, NSLayoutManager干以下事情:

  • 控制text storage 和text container
  • 从characters生成glyphs
  • 计算字形的位置并且保存信息
  • 管理字形和字符的范围
  • 在text view中绘制glyphs
  • 计算文本行的边框矩形
  • 控制连字符
  • 操作字符属性和字形属性

4.The Layout Process

Layout Manager执行布局分为2步:字形生成和字形布局,

5.Generating Line Fragment Rectangles

layout manager 会使用[lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect:]方法像text container 获得一个矩形区域用来放置文本(Line Fragment Rectangles),然后会根据lineFragmentPadding属性来调整该矩形区域的padding(不要使用该属性来调整整个文档的边距),
除了返回Line Fragment Rectangles还会返回一个叫做used rectangle的矩形区域,这两个矩形都包括了lineFragmentPadding和interline space,但是段落间距仅仅包含在Line Fragment Rectangles中,used rectangle没有

你可能感兴趣的:(TextKit官方文档阅读笔记)