Highlight
Swan’s Quest 第一章让开发者在 Swift Playgrounds 中用 VoiceOver 和 AccessibilityHints 给洞穴里的 torch 图形补上可朗读标签,从而把看不见的关卡变成可导航的编程挑战。
核心内容
Swan’s Quest 是 WWDC 2020 的四章 Swift Playgrounds 挑战。第一章把玩家放进一个黑暗洞穴:角色看不到路,也不会移动,除非你用 VoiceOver 找到屏幕上的 torch,并给它们补上有意义的标签。(00:41)
这个设定把无障碍问题变成了一个可玩的任务。没有标签时,VoiceOver 只能读出 “Torch two, graphic” 这类几乎没有上下文的信息;演讲者把这种体验类比成 app 里一串未命名按钮,用户只能听到 “button, button, button”。(09:13)
Apple 给出的解决路径很直接:先学习 VoiceOver 的基本导航,再使用 Swift Playgrounds content SDK 里的 Accessibility APIs。Graphic、Button、Sprite、Label 都继承自 BaseGraphic,这些元素可以通过 accessibilityHints 暴露给 VoiceOver 和其他辅助服务。(11:48)
最后的挑战落在代码上。你要把不清楚的 torch 名称替换成描述性的 accessibilityLabel。当 VoiceOver 停到某个 torch 上时,它读出的内容会告诉玩家位置、危险或线索,角色才有足够信息穿过洞穴去见 Swan。(13:09)
详细内容
让 Playgrounds 图形拥有无障碍入口
(12:21)Swift Playgrounds content SDK 里的 Graphic、Button、Sprite 和 Label 都继承自 BaseGraphic。BaseGraphic 提供了可选的 accessibilityHints,这是把屏幕元素交给 VoiceOver 的入口。
// Graphic.swift
open class BaseGraphic: InternalGraphic {
public var accessibilityHints: AccessibilityHints?
// ...
}
关键点:
BaseGraphic是这些屏幕元素的共同基础,所以同一套无障碍提示可以覆盖多类内容。accessibilityHints是可选属性,只有需要暴露给辅助服务的元素才需要设置。- 演讲明确说,设置这个属性会让屏幕元素被 VoiceOver 读取,并让其他辅助服务可见。
定义 VoiceOver 是否停留和读什么
(12:32)AccessibilityHints 至少需要两个信息。makeAccessibilityElement 决定 VoiceOver cursor 是否停在这个元素上;accessibilityLabel 是 VoiceOver 停住时朗读的文本。
// AccessibilityHints.swift
public struct AccessibilityHints: Codable {
/// Indicates a graphic should be treated as a UIAccessibilityElement by VoiceOver.
public var makeAccessibilityElement: Bool = false
/// Label spoken by VoiceOver for the accessible graphic (a localized character name).
public var accessibilityLabel: String?
// ...
}
关键点:
makeAccessibilityElement设为true后,VoiceOver 才会把这个图形当作可停留的元素。accessibilityLabel要写给使用者听,不是写给开发者调试;洞穴里的 torch 需要描述位置和含义。- 结构体是
Codable,这符合 playground book 内容可以被打包、下载和检查的使用方式。
把提示绑定到具体图形
(12:45)演讲用一个按钮式图形示例说明流程:先创建 AccessibilityHints,再创建 Graphic,最后把提示赋给图形。
// Make an Accessible Graphic
import SPCCore
import SPCAccessibility
let hints = AccessibilityHints(makeAccessibilityElement: true,
accessibilityLabel: "Activate button to start the party")
let graphic = Graphic(name: "Let's get it Started")
graphic.accessibilityHints = hints
关键点:
SPCCore提供Graphic等内容 SDK 类型。SPCAccessibility提供AccessibilityHints。AccessibilityHints(makeAccessibilityElement: true, accessibilityLabel: ...)同时完成焦点暴露和朗读文本设置。graphic.accessibilityHints = hints是让这个图形真正进入 VoiceOver 路径的动作。
把抽象示例落到洞穴 torch
(13:51)第一章的实际任务是给洞穴里的 torch 写标签。标签不是装饰文案,它直接决定玩家在黑暗场景中能不能理解当前位置。
// activate torch1 and torch2
cave.torch1.accessibilityHints = AccessibilityHints(makeAccessibilityElement: true,
accessibilityLabel: "Torch next to a stairwell, where dripping water can be heard.")
cave.torch2.accessibilityHints = AccessibilityHints(makeAccessibilityElement: true,
accessibilityLabel: "Right before the edge of the platform—be careful!")
关键点:
cave.torch1和cave.torch2是关卡里的具体图形对象。- 两个 torch 都设置了
makeAccessibilityElement: true,所以 VoiceOver 可以逐个停留。 - 第一个标签描述了楼梯和滴水声,给玩家位置线索。
- 第二个标签提示平台边缘,给玩家行动风险。
- 这段代码对应演讲结尾的要求:用耳朵检查标签,把无用名称改成描述性内容。
核心启发
-
做一个 VoiceOver 优先的关卡:让玩家关掉视觉线索,只通过 VoiceOver 标签完成导航。为什么值得做:session 直接把黑暗洞穴做成无障碍训练场,玩家必须依赖描述性标签前进。怎么开始:把关键
Graphic对象设置accessibilityHints,再用accessibilityLabel描述位置、危险和目标。 -
给自定义控件做一分钟删除测试:打开 app 后只用 VoiceOver 浏览第一屏,记录所有只读出 “button”、“graphic” 或文件名的元素。为什么值得做:演讲者说未命名按钮会在第一分钟劝退用户。怎么开始:从最常用流程开始,给每个按钮、图片和自定义图形补上可执行或可理解的标签。
-
把 Swift Playgrounds book 变成可 remix 的教学材料:为每个练习页提供可下载的 starting point,让学习者打开后能直接查看内容 SDK 的用法。为什么值得做:Swan’s Quest 和模板都能从 Developer app 下载,开发者可以拆开看 Apple 如何构建挑战。怎么开始:准备一个最小 playground book,放入一页使用
Graphic和AccessibilityHints的任务。 -
把声音和环境线索写进标签:不要只写物体名称,而要写玩家做决定需要的信息。为什么值得做:洞穴示例里的滴水声、楼梯和平台边缘都帮助玩家理解空间。怎么开始:让设计稿里的每个关键视觉线索都有一条对应的 VoiceOver 文案。
-
让无障碍检查成为内容发布步骤:每次发布 Playgrounds 内容前,用 iPad 或 Mac 打开 VoiceOver 走完整个挑战。为什么值得做:session 先教开启 VoiceOver 和基本手势,再要求用它完成关卡。怎么开始:用 Accessibility Shortcut 或 Command-F5 开启 VoiceOver,逐项确认焦点顺序和标签内容。
关联 Session
- App accessibility for Switch Control — 说明 Switch Control 如何复用无障碍信息,并用焦点顺序、自定义操作和分组降低操作成本。
- Make your app visually accessible — 从颜色、文字、动效和视觉设置检查界面是否适合更多视觉能力的用户。
- Create a seamless speech experience in your apps — 讲解 AVSpeechSynthesizer、VoiceOver announcement 和辅助技术语音设置之间的边界。
- VoiceOver efficiency with custom rotors — 深入 VoiceOver 用户在复杂界面里的导航效率和自定义 Rotor。
- Accessibility design for Mac Catalyst — 把 iPad App 带到 Mac Catalyst 时,补齐键盘、鼠标、分组和检查工具等无障碍细节。
评论
GitHub Issues · utterances