What's new in TextKit and text views
System & Services 进阶 20m

TextKit 和文本视图的新功能

What's new in TextKit and text views

2022年6月6日

在 Apple 官方观看视频

一句话判断

TextKit 2 在 iOS 16 和 macOS Ventura 中成为所有文本控件的默认引擎——如果你的应用涉及自定义文本布局,现在就是迁移的最佳时机。

这场 Session 讲了什么

TextKit 工程师 Donna Tom 介绍了 TextKit 2 的最新进展和迁移指南。TextKit 2 在 iOS 15 中首次引入(仅 UITextField),iOS 16 完成了 UIKit 的全面迁移——UITextView 也默认使用 TextKit 2。AppKit 方面,macOS Ventura 中所有文本控件都默认使用 TextKit 2。

Session 介绍了 TextKit 2 的新功能(非简单文本容器、均匀断行、文本列表支持)、TextKit 1 兼容模式的机制、以及从 TextKit 1 迁移到 TextKit 2 的策略。

核心信息是:对于不做特殊文本视图修改的应用,迁移可能是零代码的。对于深度依赖 TextKit 1 的应用,Apple 提供了兼容模式确保继续可用。

值得深挖的点

零代码迁移的可能性。 大多数文本视图会自动选择使用 TextKit 2,不需要任何代码改动。只有在少数情况下(如使用 NSLayoutManager API、使用 TextKit 2 尚不支持的属性如表格、或需要打印)会回退到 TextKit 1 兼容模式。

非简单文本容器。 TextKit 2 现在支持带有孔洞或间隙的文本容器。使用 exclusionPaths 属性定义文本不应排版的区域,文字会自动围绕图片或其他内联内容排列。

均匀断行。 TextKit 2 增强了断行引擎,为两端对齐段落选择更均匀的断行位置。效果是减少了拉伸的行和过大的词间距,文本整体更易阅读。这个改进无需任何代码即可获得。

文本列表的树形结构。 TextKit 2 为 NSTextElement 增加了树形结构支持,新增 NSTextListElement 子类来表示列表项。嵌套列表现在有了更自然的表示方式。NSTextList 也从 AppKit-only 扩展到了 UIKit。

Text Attachment View Provider。 TextKit 2 的新 API 允许你将 UIView 或 NSView 作为文本附件,事件可以直接由附件视图处理。这大大简化了文本中嵌入交互式内容的工作。

代码片段

import UIKit

// 创建明确使用 TextKit 2 的 UITextView
let textView = UITextView(usingTextLayoutManager: true)

// 创建使用 TextKit 1 兼容模式的 UITextView
let legacyTextView = UITextView(usingTextLayoutManager: false)

// 非简单文本容器:文字围绕图片排列
let textContainer = NSTextContainer()
textContainer.exclusionPaths = [
    UIBezierPath(rect: imageRect)  // 图片占据的区域
]

// 创建文本列表
let list = NSTextList(markerFormat: .disc, options: 0)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.textLists = [list]

let attributedString = NSAttributedString(
    string: "第一项\n第二项\n第三项",
    attributes: [.paragraphStyle: paragraphStyle]
)

// 监听意外回退到 TextKit 1 的日志警告
// 设置断点:_UITextViewEnablingCompatibilityMode
// 检查控制台输出中关于兼容模式切换的信息

最佳实践

  • 尽快迁移到 TextKit 2——未来的性能优化和功能更新都集中在 TextKit 2 引擎上
  • 对于不做特殊文本处理的应用,直接构建运行即可,大部分会自动使用 TextKit 2
  • 如果应用意外回退到 TextKit 1,在断点 _UITextViewEnablingCompatibilityMode 处检查原因
  • 使用新的 usingTextLayoutManager 构造器明确指定文本引擎
  • 利用 Interface Builder 中新的 Text Layout 选项按实例控制使用哪个引擎
  • 非简单文本容器配合 exclusionPaths 可以实现图文混排
  • TextKit 2 的文本附件视图提供者 API 让内联交互内容更易实现

还有什么值得关注

  • TextEdit 在 macOS Ventura 中全面使用 TextKit 2,包括富文本模式
  • TextKit 2 暂不支持表格和打印,这些场景仍会使用 TextKit 1 兼容模式
  • 配套观看 “Meet TextKit 2”(WWDC 2021)了解基础概念
  • 官方的 TextKitAndTextView 示例代码涵盖了 exclusionPaths、文本列表和文本附件等用法
WWDC 2022