-
使用 PencilKit 解读笔触之间的奥秘
运用“无边记”和“备忘录”等 Apple App 背后的强大技术,为你的 App 解锁手写识别功能。了解如何在各种字母和语言中使用手写识别,并探索如何利用新功能将 PencilKit 整合到多种多样的 App 中。
章节
- 0:00 - Introduction
- 3:25 - Handwriting recognition
- 8:38 - Path conversion
- 10:21 - Improved model access
- 11:25 - Stroke slicing
- 13:48 - Next steps
资源
- Controlling stroke rendering for animation and editing
- Recognizing handwriting and converting it to text
- Building a handwriting recognition experience with PencilKit
- PencilKit
相关视频
WWDC26
WWDC25
WWDC20
-
搜索此视频…
欢迎! 我是Yichen 一位负责 绘图功能的工程师 在本场次中 我将向你展示 PencilKit中令人兴奋的新API 这些API可为你的App 带来手写识别功能 以及对绘图模型 更深入的访问 这将开启各种有趣的使用场景 用Apple Pencil在iPad上书写 感觉与用笔在纸上书写一样自然 但与纸张不同的是 你的手写内容将变得可搜索 可识别 且具有交互性 PencilKit是支持 自由绘图的核心框架 适用于Apple的各个平台 它为你提供低延迟画布 以及富有表现力的墨迹 完整的Apple Pencil支持 以及对底层数据模型的访问 iOS 26引入了PaperKit 它构建于PencilKit之上 在系统范围内提供 Apple的绘图体验 本场次涵盖的所有 PencilKit新API 在使用PaperKit时同样适用 要了解更多内容 请观看"Meet PaperKit"视频 来自WWDC25 以及WWDC26的 "Unwrap PaperKit"视频 Apple各平台拥有 世界一流的手写识别功能 你已见过它驱动各项功能 例如在“无边记”和“备忘录”中 搜索手写内容 PencilKit中呼声最高的功能 之一是手写识别 现在它已在iOS中向你开放 iPadOS macOS和visionOS 27中 我将从PencilKit的 手写识别API开始介绍 向你展示如何将 手写内容转换为识别文字
接下来 我将介绍新的转换API 让你能够相互转换 PencilKit笔画路径与 标准贝塞尔路径之间的格式 然后 我将介绍 绘图模型的改进 包括笔画标识 和选择访问
最后 我将展示 新的笔画切片API 让你能够拆分笔画 或提取笔画片段 我一直在iOS 27中使用PencilKit 为儿子构建一个学习App 练习书写中文和英文 在我的App中 他可以 练习用两种语言书写单词 并获得书写反馈 这里 App显示一张 以英文展示单词的闪卡 为了练习 我将书写 该单词的中文翻译 目前它显示的是 英文单词"Heart" 所以我需要用中文写"心" 现在 App可以使用 手写识别功能 在我完成整个汉字之前 就检查我当前的书写
检查按钮抖动 告诉我答案不对
这次App将我的手写内容 识别为中文汉字"心" 与提示词匹配 App确认答案正确 太棒了! 这就是PencilKit中 手写识别API能做的事
我将从手写识别的 核心部分开始介绍 PKStrokeRecognizer是一个Swift Actor 因此在设计上是线程安全的 所有方法都是异步的 因为识别需要时间 有三项主要功能 它们共同提供 一种手写识别体验 对你的App大有裨益 我将逐一介绍 第一项功能是识别文本 它返回书写内容 最有可能的单个结果
默认情况下 PKStrokeRecognizer 使用设备语言来判断 如何解读手写内容 你也可以明确配置 preferredLanguages 以匹配App的语言环境
你可以一次性 识别整幅绘图 也可以传入特定的strokeID子集 我将滑至开放式练习视图 展示识别文本的实际效果
我可以在这里写任何内容 PencilKit会将其识别出来
太棒了! Hello WWDC
在iOS 27中 PKStrokeRecognizer 支持29种语言 支持的语言列表 可通过以下方式访问 PKStrokeRecognizer上的 supportedLanguages属性 请注意 Simulator中的 手写识别仅支持 使用拉丁字符的语言 PencilKit中的手写识别 完全在设备上运行 识别模型可离线使用 并随操作系统一同提供 手写识别速度很快 并适用于iOS 27 支持的所有设备 下一个API是可索引内容 它提供一个字符串 表示整幅绘图的内容
这对于Spotlight搜索 等功能特别有用
当多种语言处于活跃状态时 可索引内容可能包含结果 以多种语言呈现 当手写内容存在歧义时 你希望获得所有可能的解读 放入索引 这样无论用户搜索什么 都能找到他们的内容 这是"1"还是小写字母"L"? 这是"101"还是"lol"? 识别文本只给出 一个最佳答案 而可索引内容则将 所有候选结果连接在一起 如果你要将可索引内容 持久化到磁盘 请记住 识别结果 会随着底层模型的更新 而不断改善
PKStrokeRecognizer提供了 recognizerVersion属性 将其与indexedContent一起存储 加载时 与当前版本进行比较 以决定是否重新索引
此外 考虑对 PKStrokeRecognizer的调用进行节流
每次笔画都更新结果 可能消耗更多电量 超出实现索引功能的需要 第三个API用于搜索文本
给定一个目标字符串 它返回一个搜索结果数组 表明该单词可能出现 在绘图中的哪些位置
综合考虑所有候选结果
这就是交互式搜索的驱动力 匹配的笔画周围 会出现高亮显示
search()也可以与 UIFindInteraction自然配合
即系统查找和替换体验
通过实现UIFindInteractionDelegate 并在底层使用search()驱动
你将获得系统搜索界面 完整支持结果导航 和高亮显示 直接在你的绘图画布中 回到闪卡 我做了一处修改 展示搜索功能如何 驱动闪卡匹配
我添加了SearchResults 返回边界的可视化效果
现在有一个框 显示搜索匹配的位置
这些功能还使手写内容 更易于访问 你可以连接VoiceOver 朗读手写内容 让依赖屏幕阅读器的用户 也能访问手写内容 搜索功能让辅助功能 定位并导航到特定单词 在绘图中 它们共同帮助弥合 无障碍访问方面的差距 手写文本与打字文本之间 接下来是路径转换 路径转换是一套强大的API 帮助你将PencilKit 引入App中
PencilKit以三次均匀B样条 表示笔画路径 有关PencilKit 如何存储路径的更多信息 请观看"Inspect, modify, and construct PencilKit drawings"— WWDC20
B样条是绘图的出色表示方式 但不如贝塞尔路径常见 在iOS 27中 PKStrokePath 支持两者之间的转换
转换路径时 PencilKit负责处理几何图形 贝塞尔路径不携带大小 不透明度等PencilKit属性 因此你需要为每个控制点 提供这些属性
从PKStrokePath开始 转换至贝塞尔路径再转回 将得到相同的控制点位置 支持以贝塞尔路径格式 存储PencilKit笔画 并可无损还原 如果你的App拥有自己的画布 且笔画以贝塞尔路径存储 现在你可以将这些路径 转换为PKStrokePaths 构建PKDrawing 并传入PKStrokeRecognizer 这使手写识别 与任何画布都兼容 而不仅限于PKCanvasView
除了扩展PencilKit的使用范围 iOS 27还引入了 重要的新增功能 可更深入访问模型 这种灵活性支持App中 更多自定义使用场景
PKStroke和PKStrokePath均获得 Identifiable协议的一致性 这是一个稳定的UUID 你可以跨变换 编辑追踪笔画 以及撤销操作
有了稳定的标识 你现在可以控制选择状态 在PKCanvasView上
还有一个新的委托方法 canvasViewSelectionDidChange 每当用户的选择发生变化时触发 当某些墨迹快速绘制在一起时 PencilKit将这些笔画 合成在一起 就好像墨迹还未干一样 通过相同的renderGroupID 在iOS 27中 这现在可控 最后一组新API让你能够 以两种方式切片笔画 两种不同的方式: 程序化擦除 和子笔画提取 如果你曾使用过 PencilKit的数据模型 你可能已经熟悉笔画蒙版 PencilKit使用蒙版 表示部分擦除 当像素橡皮擦 擦除笔画的一部分时 剩余的可见部分 由蒙版定义 从iOS 27开始 你可以 以编程方式应用相同的操作 你提供一个PKStrokePath作为橡皮擦
它切穿绘图 将单个笔画切片 成多个独立笔画 各自带有蒙版 就像用户在画布上 使用了橡皮擦工具一样
需要注意的是 切片 在复杂绘图中可能代价较高
如果绘图包含大量笔画 请注意性能 考虑在后台线程中 进行擦除操作 而不是阻塞UI
当擦除在视觉上切断笔画时 子笔画提取让你能够 高效获取某个片段 作为新笔画或路径
从iOS 27开始 PKStroke和PKStrokePath 均支持下标访问 沿路径任意位置 使用参数范围 让你精确控制 切片的起始和结束位置
PencilKit墨迹具有 铅笔纹理颗粒等特性 这些颗粒的位置 相对于完整笔画
提取子笔画时 PencilKit会保持 这些颗粒的一致性 对于汉字 书写笔画的顺序 非常重要 为了检查顺序是否正确 我使用子笔画构建了一项功能 来回放书写过程
PencilKit使用Metal实现渲染 通过优化使我的动画 流畅运行
充分利用这些强大API 采用PKStrokeRecognizer 为你的App带来手写识别功能
在新场景中尝试PencilKit 将现有的贝塞尔路径 转换为PKStrokePaths 利用手写识别功能 即使没有PKCanvasView 深入探索PencilKit的模型 用稳定标识追踪笔画 响应选择变化 构建全新水准的自定义体验 最后 充分利用笔画切片 用程序化擦除 切穿绘图 用子笔画构建 流畅的动画
每个API都易于集成 它们共同解锁了App中 此前无法实现的功能
本演示的示例代码 可在本视频的资源中找到 手写内容变得可识别 可搜索且具有交互性 遍及你的整个App 这就是iOS 27中的PencilKit 感谢观看!
-
-
3:53 - Recognized text
import PencilKit let recognizer = PKStrokeRecognizer() await recognizer.updateDrawing(drawing) myLabel.text = await recognizer.recognizedText() -
5:22 - Indexable content
import PencilKit let recognizer = PKStrokeRecognizer() await recognizer.updateDrawing(drawing) if let indexedContent = await recognizer.indexableContent { index(text: indexedContent) } -
6:58 - Find text
import PencilKit let recognizer = PKStrokeRecognizer() await recognizer.updateDrawing(drawing) let results = await recognizer.search("apple") for result in results { highlight(bounds: result.bounds) }
-
-
- 0:00 - Introduction
Meet the PencilKit APIs behind handwriting in Notes and Freeform, now available to your apps in iOS 27.
- 3:25 - Handwriting recognition
Use the stroke recognizer API for on-device text recognition, indexing, search, and accessibility.
- 8:38 - Path conversion
Converting PKStrokePath to and from Bézier paths without losing fidelity, so apps that store strokes as Bézier can build PKDrawings and use handwriting recognition on any canvas, not just PKCanvasView.
- 10:21 - Improved model access
Deeper access to the drawing model in iOS 27 — stable Identifiable stroke IDs that survive edits and undo, controllable canvas selection with a change delegate, and adjustable wet-ink render groups.
- 11:25 - Stroke slicing
Two ways to slice strokes — programmatic erasing that cuts one stroke into independent strokes, and substroke extraction with parametric ranges — along with performance considerations for complex drawings.
- 13:48 - Next steps
Ways to put these APIs to work: adopt PKStrokeRecognizer for handwriting recognition, convert existing Bézier paths, track strokes with stable identity, and use stroke slicing for erasing and animation.