Text Programming Guide for iOS

摘录自Apple官方文档Text Programming Guide for iOS

简介(About Text Handling in iOS)

排版概念(Typographical Concepts)

字符和字形(Characters and Glyphs)

字符:A character is the smallest unit of written language that carries meaning.
字形:Any one of these various concrete forms of a character is called a glyph.

字形度量Glyph Metrics
Text Programming Guide for iOS_第1张图片

字符A的字形
Text Programming Guide for iOS_第2张图片

字符和字形并没有一一对应的关系。某些情况下,字符可以由多个字形来表示。例如,“é”由字形 “e”“´”组合而成。另一种情况是,一个单独的字形可描绘出多个字符,例如,连写(ligature)。

连写ligature
Text Programming Guide for iOS_第3张图片

字体(Typefaces and Fonts)

Typefaces:A typeface is a set of visually related shapes for some or all of the characters in a written language.
Font:A font is a series of glyphs depicting(描绘) the characters in a consistent(一致的) size, typeface, and typestyle.
font family:A font family is a group of fonts that share a typeface but differ in typestyle.例如,Times是一个font family名。Times roman 和Times Italic是两个独立的fonts,都属于Times font family。

Fonts in the Times font family
Text Programming Guide for iOS_第4张图片

使用Text Kit来绘制和管理Text

Text Kit是基于Core Text的
Text Programming Guide for iOS_第5张图片

Text Kit主要对象

Text Kit主要对象之间的关系如下图所示。Text views是UITextView的实例,text containers是NSTextContainer类的实例,layout manager是NSLayoutManager类的实例。text storage是NSTextStorage类的实例。在Text Kit中,一个NSTextStorage对象存储UITextView显示的text,使用NSLayoutManager对象来布局到NSTextContainer对象定义的区域。

NSTextContainer定义了text布局的区域。通常,一个text container定义了一个矩形区域,但是,通过继承NSTextContainer,你可以创建其它的形状:圆形,五角形,或者其它不规则形状。text container不仅定义了text填充区域的外形,而且还可以持有一个贝塞尔曲线的集合,用来指定不可填充文本的区域。

NSTextStorage定义Text Kit最基本的存储机制。它继承自NSMutableAttributedString。除了存储文本,NSTextStorage还管理一系列NSLayoutManager对象,通知它们字符或者熟悉改变了,来让它们重新显示文本。

NSLayoutManager统筹处理text的操作。

文本属性(Text Attributes)

Text Kit处理三种文本属性:character attributes,paragraph attributes和document attributes。字符属性包括字体、颜色和下标,作用于单个字符或者某个范围的字符。段落属性包括缩进,制表符(tabs),和行间距。文档属性包括页面大小、边距和缩放比例。

字符属性(Character Attributes)

属性字符串在NSDictionary对象中以键值对的方式来存储字符属性。

NSAttributedString类提供了方法,通过一个字符索引,来返回相应的属性字典和属性应用的范围,例如attributesAtIndex:effectiveRange:.

NSTextStorage对象使用NSMutableAttributedString的方法addAttribute:value:range:在相应的字符范围添加属性。addAttributes:range:使用字典来添加属性。

为使用你自定义的属性,你需要继承NSLayoutManager。子类需要重写drawGlyphsForGlyphRange:atPoint:方法。重写的方法首先调用父类的方法来绘制glyph range,然后再在上面绘制你自己的属性。另一种方式是,重写方法完全以你自己的方法来绘制字形。

段落属性(Paragraph Attributes)

NSParagraphStyle类定义了段落属性。

文档属性(Document Attributes)

虽然text system没有内置的存储文档属性的机制,NSAttributedString的初始化方法,initWithRTF:documentAttributes:方法can populate an NSDictionary object that you provide with document attributes derived from a stream of RTF or HTML data.相反的,ethods that write RTF data, such as RTFFromRange:documentAttributes:, write document attributes if you pass a reference to an NSDictionary object containing them with the message.

属性修正(Attribute Fixing)

正在编辑的属性字符处可能会出现不一致,必须使用attribute fixing来清除。NSMutableAttributedString定义了一个fixAttributesInRange: 方法来修正attachment,attachment和paragraph属性间的不一致。

使用程序来改变Text Storage

编辑一个text storage对象有三个步骤。
第一阶段是发送一个beginEditing消息来声明一组变化(announce a group of changes)。

第二阶段是,发送一些编辑信息,例如 replaceCharactersInRange:withString:setAttributes:range:。每次你发送这样的消息,text storage对象会调用edited:range:changeInLength:来追踪受影响字符的范围。

第三阶段是,当完成改变text storage对象后,发送endEditing消息。这会调用代理textStorage:willProcessEditing:range:changeInLength:方法,并调用自己的processEditing方法。

在修正属性后,text storage对象会给代理的textStorage:didProcessEditing:range:changeInLength:方法发送消息,给代理一个机会来确认和改变属性。最后,text storage会每一个相关的layout manager发送processEditingForTextStorage:edited:range:changeInLength:invalidatedRange:消息。layout managers使用这个消息来重新计算字形的位置,必要的话就重新显示。

布局Text

NSLayoutManager类是控制text显示的核心对象。它的作用如下:

  • 控制text storage和text container对象(Controls text storage and text container objects)
  • 有字符生产字形(Generates glyphs from characters)
  • 计算字形的位置并存储信息(Computes glyph locations and stores the information)
  • 管理字符和字形的range(Manages ranges of glyphs and characters)
  • 当view请求的时候,就在text views中绘制字形(Draws glyphs in text views when requested by the view)
  • 计算每一行的text的bounding box(Computes bounding box rectangles for lines of text)
  • 控制断字(Controls hyphenation)
  • 控制字符属性和字形属性(Manipulates character attributes and glyph properties)

NSTextStorage相当于是模型,保存有字符和属性,如typeface, style, color, 和 size。NSTextContainer也可被认为是模型的一部分,它被认为是在页面上text布局的几何形状模型。UITextView(获取其他UIView对象)提供view。NSLayoutManager做控制器。

布局过程

layout manager执行text布局有两个单独的步骤:生成字形(glyph generation)和布局字形(glyph layout)。

生产Line Fragment矩形

对于给定的一行,layout manager会给出一个矩形。然后会要求text container来调整矩形来适合。这个给出的矩形通常会超出text container的边界,但是它可以宽点或者窄点,它也可以完全或者部分的位于边框外。layout manager发送给text container来调整给出的矩形的消息是lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect:,这个方法,会返回largest rectangle available for the proposed rectangle,基于text布局的方向。

当text最终适合矩形时,layout manager会做一个最终的调整。

指定不可填充路径(Specifying Exclusion Paths)

Text Programming Guide for iOS_第6张图片

指定多页和多层布局

下面简单的例子中,Text Kit对象被逐一的配置,一个text storage对象,一个text container,和一个layout manager。当一个text view从Interface Builder中拖出来后,这个配置就自动的被实例化。

也可用用代码来创建。

NSTextStorage* textStorage = [[NSTextStorage alloc] initWithString:string];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
self.textContainer = [[NSTextContainer alloc] initWithSize:self.view.bounds.size];
[layoutManager addTextContainer:self.textContainer];
UITextView* textView = [[UITextView alloc] initWithFrame:self.view.bounds textContainer:self.textContainer];
[self.view addSubview:textView];

这个仅有一个text container和一个text view。
使用多个text containers,每个关联一个text view,就可以实现更复杂的布局。例如,支持分页
Text Programming Guide for iOS_第7张图片

Object configuration for multicolumn text

不仅仅支持多个text container,还可以支持多个NSLayoutManager对象。
Object configuration for multiple views of the same text

你可能感兴趣的:(ios,苹果,text-kit)