大多数浏览器和
Developer App 均支持流媒体播放。
-
开始使用 Writing Tools
了解 Writing Tools 如何帮助用户校对、改写和转换在 App 中输入的文本。详细了解 Writing Tools 如何与你的 App 交互,以便用户可以在任一文本视图中改进已编写的内容。了解文本的检索和处理方式,以及如何为自定文本视图中的 Writing Tools 使用提供支持。
章节
- 0:00 - Introduction
- 3:42 - Native text views
- 7:03 - Controlling behavior
- 8:23 - Protecting ranges
- 9:03 - Custom text views
- 11:44 - Next steps
资源
相关视频
WWDC23
WWDC22
WWDC21
WWDC19
-
下载
大家好 欢迎观看 “开始使用 Writing Tools”讲座 我叫 Liu Dongyuan 负责文本输入 和国际化工作 Writing Tools 是一套全新功能 可在各种 App 的 文本视图中使用 帮助用户润色他们 正在处理的任何文本 在这个讲座中 我将介绍 Writing Tools 然后说明 Writing Tools 如何与原生文本视图交互 如何控制 Writing Tools 的行为 让它更适合你的 App 如何保护文本范围 例如引用内容和代码块 以及如何为自定文本视图 提供 Writing Tools 支持 我们先来了解一下 Writing Tools Writing Tools 可帮助用户 对iOS、iPadOS 和 macOS 上的 文本视图中的文本 进行校对、改写或转换 建议能直接内联显示 方便用户快速顺畅地 查看并整合更改 在任何原生文本视图中 当你选中一段文本时 Writing Tools 都会 显示在键盘最上方 它还显示在标注栏中 位于 “剪切”、“拷贝”和“粘贴”旁边
在 macOS 上 Writing Tools 位于上下文菜单和“编辑”菜单中
当你将鼠标悬停在原生 文本视图中的选定文本上 将会显示一个图标 引导你打开 Writing Tools 面板 你可以通过这种简单的方式 直接从文本中调用 Writing Tools 我们来详细了解一下 Writing Tools 有哪些功能
它可以校对文本 并显示拼写错误 和语法错误等错误 你可以逐一查看 Writing Tools 中的建议
Writing Tools 可以改写文本 或者让文本变得 更友好、更专业、更简洁 Writing Tools 可以总结文本 将文本转换为要点 甚至还能将文本 转换为列表或表格 Writing Tools 还适用于 不可编辑的文本 生成的结果将显示在面板中 用户可以拷贝 或分享这些结果 接下来 我来展示其中 一些功能的实际应用 假设我们要为举办一场 Writing Tools 的发布派对 我起草了一封邀请函 在发送之前 我想确保 邀请函中没有错误
我可以从标注栏中 调用 Writing Tools 并选择“Proofread”
哇 校对完成后 可以看到 所有建议都直接内联显示 我可以轻点查看各个更改
我觉得全都改得不错 轻点“Done”即可接受更改 我还想向朋友发送一条 关于派对的简短信息 我可以使用 Writing Tools 来总结文本 缩短篇幅
然后拷贝或分享摘要信息
最后 为了筹备发布派对 我想让一些朋友 带一些物品过来 我想把清单变成漂亮的表格 我可以选中文本 调用 Writing Tools 并选择“Table”
看!
请注意 所有粗体文本 和链接都仍然存在 是不是很神奇? 正如你所见 Writing Tools 是一款功能强大的工具 可为你的文本视图 带来更多功能 当你的 App 在受支持的 环境中运行时 将自动显示 Writing Tools 接下来 我们来讨论 Writing Tools 如何与文本视图搭配使用 以及如何在 App 中 提供 Writing Tools 好消息是 如果你使用 UITextView、NSTextView 或 WKWebView 就可以直接使用这项功能
请记住 UITextView 或 NSTextView 必须使用 TextKit 2 才能支持 完整版 Writing Tools 体验 如果你使用 TextKit 1 你将获得有限的体验 只能在面板中看到改写的结果
如需进一步了解 TextKit 2 请查看链接的讲座
当你调用 Writing Tools 时 它是怎么运作的?
首先 我们可以扩展用户 选中的内容来包含完整的句子 从而通过工具获得更好的结果 我们还可以使用 所选内容前后的更多文本 确保模型了解 文本的上下文
其次 Writing Tools 可通过使用 属性字符串完全支持富文本 只要相关文本仍然 包含在改写的文本中 模型就可以保留样式、 链接和附件等属性
最后 对于列表和表格转换 如果文本视图 支持列表和表格 我们会将 NSTextList 和 NSTextTable 发送到文本存储 你可以通过使用 WritingToolsAllowedInputOptions 来控制文本视图 是否需要处理表格 我们稍后再介绍这项功能 正如你在演示中看到的 当模型忙于处理文本时 我们会在 Writing Tools 会话 处于活动状态时显示动画 在会话期间 你的 App 可能想要暂停同步 或避免意外的编辑操作 我们为 Writing Tools 引入了 新的文本视图委托方法
在 textViewWritingToolsWillBegin 中 你可以为 Writing Tools 准备 App 状态 例如 你可能需要暂停同步 或任何能够直接操控 文本存储的操作
在 textViewWritingToolsDidEnd 中 你可以恢复 App 状态 例如恢复同步
我们还在 UITextView 中提供 新的 isWritingToolsActive 属性 进行文本操作时 你可能需要了解 Writing Tools 是否也在与文本视图交互
新的委托方法和属性 同时适用于 UITextView 和 NSTextView
当文本很长时 改写的文本可以分成多个 文本块提供到文本视图中 我们对正在处理的 文本应用了动画 表明模型正在运行 模型处理完成后 用户可以轻点“Original”按钮 在原始文本和改写文本之间切换
对于校对功能 建议的更改会自动 应用到文本视图 用户可以查看 和拒绝各个建议
你可能想知道 在 Writing Tools 操作期间 你的底层文本存储 发生了什么情况 这些操作实际上都在 更改你的文本存储 这意味着 当 Writing Tools 处于活动 状态时 不应该将文本存储持久化 为了让用户能在事后 恢复到更改前的状态 Writing Tools 更改 还会被推送到撤销堆栈 你可能需要自定 Writing Tools 行为 使它更适合你的 App 我们为你提供了一些 新的文本输入特征 API
默认情况下 系统会尽可能 为 Writing Tools 提供内联体验 你无需进行任何设置 如果它不适合你的 App 你可以将 writingToolsBehavior 设置为 .limited 从而获得面板体验 或设置为 .none 让文本视图 完全停用 Writing Tools
你也可以使用 writingToolsAllowedInputOptions 来指定文本视图 是否支持富文本或表格 如果你不进行设置 我们会假设文本视图可渲染 纯文本和富文本 但不能渲染表格 如果文本视图只接受纯文本 或者能够处理表格 那么你可以明确指定选项
最后 我们还提供适用于 WKWebView 的类似 API 你可以通过 WKWebViewConfiguration 指定相同的枚举 请注意 WKWebViews 的 默认行为是 .limited 如果想实现完整的行为 你需要明确进行设置
你可以查看或观察 “isWritingToolsActive”属性 以了解 Writing Tools 是否处于活动状态 接下来 我们来谈谈如何 为 Writing Tools 设置需要忽略的范围
假设你要实现一款 可将某些范围 标记为代码块的笔记 App 或者你有一款可以 引用内容的邮件 App 你可能不希望 Writing Tools 改写这些范围 我们可以满足这项需求! 我们在 UITextViewDelegate 和 NSTextViewDelegate 中添加了新的委托方法 只需返回你想忽略的范围 Writing Tools 就不会对 相应范围内的内容进行更改
对于 WKWebView “blockquote”和“pre”之类的标签 将被 Writing Tools 自动忽略 最后 如果 App 具有 UITextView 或 NSTextView 以外的自定文本视图 该怎么办? 好消息是 你可以轻松 获得免费的基本体验 改写的文本 将显示在面板中 用户可以拷贝、共享文本 或将文本应用到文本视图中
在 iOS 和 iPadOS 上 只要你的自定文本视图 采用 UITextInteraction 即可在标注栏或上下文菜单中 免费获得 Writing Tools 如果不能使用 UITextInteraction 你还可以搭配使用 UITextSelectionDisplayInteraction 和 UIEditMenuInteraction 本质上 Writing Tools 依赖 UITextInput 协议 来读取和编写文本 以及锚定弹出窗口 如需进一步了解文本交互 请查看往年 WWDC 的一些精彩讲座
对于不使用文本 交互的文本视图 我们在 UITextInput 协议中 添加了新的可选属性 isEditable 可以采用这个属性来指示 文本视图是否支持编辑
在 Mac 上 我们将在自定文本视图的 上下文菜单和“编辑”菜单中 自动显示 Writing Tools
确保你的文本视图采用 NSServicesMenuRequestor 这个协议允许系统 读取视图中的内容 并将内容写回视图中
在 NSResponder 中覆盖 validRequestor(forSendType:returnType:) 然后 只要在视图中 添加了上下文菜单 就可以在菜单中免费提供 Writing Tools 菜单项 这样做还可以让 App 适用于各种服务 和快捷指令 如需进一步了解 请查看 WWDC21 的“AppKit 中的新功能”讲座
下面我来通过代码 展示所有这些内容 我这里有一个简单的 视图和一些文本 以及一个提供 拷贝功能的菜单 要获得 Writing Tools 只需在 NSServicesMenuRequestor 中覆盖 validRequestor(forSendType:returnType:) 并至少实现 writeSelection 方法 对于可编辑的文本视图 还需要实现 readSelection 方法 以便 Writing Tools 可以将 改写的文本发送回文本视图 在 validRequestor 方法中 你可以检查 sendType 并确定你的文本视图 是否要处理富文本 只要做完所有这些设置 就能在上下文菜单中同时获得 Writing Tools 和服务 以上就是本次讲座的全部内容 接下来要做什么?
在你的 App 中试用 Writing Tools 在大多数情况下 你无需进行 任何设置即可使用这项功能
在 Writing Tools 运行期间 采用新的委托方法 来控制 App 状态 如果你的 App 具有 特别的需求或功能 请查看 Writing Tools 的 行为和允许的输入选项
如果你有自定文本视图 只需完成几个步骤 即可开始提供 Writing Tools 功能 最后 尽情享受写作吧! 谢谢观看!
-
-
5:28 - Text view delegate methods for Writing Tools
func textViewWritingToolsWillBegin(_ textView: UITextView) { // Take necessary steps to prepare. For example, disable iCloud sync. } func textViewWritingToolsDidEnd(_ textView: UITextView) { // Take necessary steps to recover. For example, reenable iCloud sync. } if !textView.isWritingToolsActive { // Do work that needs to be avoided when Writing Tools is interacting with text view // For example, in the textViewDidChange callback, app may want to avoid certain things when Writing Tools is active }
-
7:11 - Opt-out of the full experience
textView.writingToolsBehavior = .limited textView.writingToolsBehavior = .none
-
7:31 - Specify accepted text formats
textView.writingToolsAllowedInputOptions = [.plainText] textView.writingToolsAllowedInputOptions = [.plainText, .richText, .table]
-
7:55 - WKWebView
// For `WKWebView`, the `default` behavior is equivalent to `.limited` extension WKWebViewConfiguration { @available(iOS 18.0, *) open var writingToolsBehavior: UIWritingToolsBehavior { get set } } extension WKWebViewConfiguration { @available(macOS 15.0, *) open var writingToolsBehavior: NSWritingToolsBehavior { get set } } extension WKWebView { /// @discussion If the Writing Tools behavior on the configuration is `.limited`, this will always be `false`. @available(iOS 18.0, macOS 15.0, *) open var isWritingToolsActive: Bool { get } }
-
8:48 - Protecting ranges
// Returned `NSRange`s are relative to the substring of the textView’s textStorage from `enclosingRange` func textView(_ textView: UITextView, writingToolsIgnoredRangesIn enclosingRange: NSRange) -> [NSRange] { let text = textView.textStorage.attributedSubstring(from: enclosingRange) return rangesInappropriateForWritingTools(in: text) }
-
9:58 - Indicate your text view supports editing
protocol UITextInput { @available(iOS 18.0, macOS 15.0, *) optional var isEditable: Bool { get } }
-
10:58 - Simple view that supports Copy
class CustomTextView: NSView, NSServicesMenuRequestor { required init?(coder: NSCoder) { super.init(coder: coder) self.menu = NSMenu() self.menu?.addItem(NSMenuItem(title: "Custom Text View", action: nil, keyEquivalent: "")) self.menu?.addItem(NSMenuItem(title: "Copy", action: #selector(copy(_:)), keyEquivalent: "")) } override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) // Custom text drawing code... } }
-
11:05 - View extension to support Writing Tools
class CustomTextView: NSView, NSServicesMenuRequestor { override func validRequestor(forSendType sendType: NSPasteboard.PasteboardType?, returnType: NSPasteboard.PasteboardType?) -> Any? { if sendType == .string || sendType == .rtf { return self } return super.validRequestor(forSendType: sendType, returnType: returnType) } nonisolated func writeSelection(to pboard: NSPasteboard, types: [NSPasteboard.PasteboardType]) -> Bool { // Write plain text and/or rich text to pasteboard return true } // Implement readSelection(from pboard: NSPasteboard) as well for editable view }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。