为 Switch Control 优化 App 无障碍体验
App accessibility for Switch Control
2020年6月23日
一句话判断
如果你从未考虑过 Switch Control 用户如何使用你的 App,这场 Session 是一个低成本入门——你会发现只要做好 VoiceOver 标注,大多数场景下 Switch Control 就自然能工作。
这场 Session 讲了什么
Switch Control 是 iOS 内置的辅助功能,允许运动障碍用户通过一个或多个外部开关(如按键、吹气传感器、头部追踪)来操控设备。它通过扫描界面上的可交互元素,用户在想要的元素上触发开关即可完成操作。
Session 首先讲解了 Switch Control 的两种模式:Item Scan(逐项扫描)和 Point Scan(点扫描)。然后通过实际演示展示了 Switch Control 用户如何在不同类型的 App 中导航。核心信息是:如果你的 App 已经正确实现了 VoiceOver 支持(UIAccessibility 标注),Switch Control 大多数情况下能正常工作。
但也有一些 Switch Control 特有的优化点:减少不必要的可交互元素(避免扫描过多项目)、合理设置 accessibility traits(让系统知道某个元素是按钮还是纯文本)、以及确保自定义手势操作的替代方案。
值得深挖的点
VoiceOver 和 Switch Control 的关系。 两者共享同一套 Accessibility 树。VoiceOver 用户通过滑动选择元素,Switch Control 用户通过扫描选择元素,但它们依赖的底层信息(标签、Traits、Value 等)完全相同。这意味着做好 VoiceOver 支持就等于做好了 Switch Control 的大部分工作。
减少”噪音”元素的重要性。 Switch Control 在扫描时会遍历所有可访问的元素。如果你的界面有大量装饰性元素被错误标记为可交互的,Switch Control 用户需要等待更长的扫描周期。合理使用 isAccessibilityElement = false 隐藏不重要的元素。
代码片段
// 正确设置自定义视图的无障碍属性
class CustomButton: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
// 标记为可交互的无障碍元素
isAccessibilityElement = true
accessibilityLabel = "播放音乐" // 清晰描述操作
accessibilityTraits = .button // 标记为按钮类型
accessibilityHint = "双击以开始播放" // 提示操作结果
}
}
// 隐藏装饰性元素,减少扫描噪音
class DecorativeImageView: UIImageView {
override init(image: UIImage?) {
super.init(image: image)
isAccessibilityElement = false // 装饰性图片不需要被扫描到
}
}
// 对分组元素使用无障碍容器
class MediaControlsView: UIView {
override func accessibilityElementCount() -> Int {
return 3 // 只暴露三个关键控件:上一曲、播放、下一曲
}
}
// 为复杂自定义控件提供完整的无障碍信息
class CustomSlider: UIControl {
var value: Float = 0.5
func updateAccessibility() {
isAccessibilityElement = true
accessibilityLabel = "音量"
accessibilityValue = "\(Int(value * 100))%"
accessibilityTraits = [.adjustable, .button]
}
// 支持 Switch Control 的增减操作
override func accessibilityIncrement() {
value = min(value + 0.1, 1.0)
updateAccessibility()
sendActions(for: .valueChanged)
}
override func accessibilityDecrement() {
value = max(value - 0.1, 0.0)
updateAccessibility()
sendActions(for: .valueChanged)
}
}
最佳实践
- 先做好 VoiceOver 再考虑 Switch Control。 两者的底层标注是共享的,VoiceOver 做好了,Switch Control 通常也能正常使用。
- 减少不必要的可交互元素。 装饰性图片、间距占位符等应设为
isAccessibilityElement = false,让扫描更高效。 - 为自定义控件实现 accessibilityIncrement/Decrement。 对于滑块、选择器等连续值控件,这两个方法让用户可以通过开关逐步调整。
- 测试时启用 Switch Control 真实体验。 在设置 > 辅助功能 > Switch Control 中开启,用屏幕开关模拟真实用户操作流程。
还有什么值得关注
- Switch Control 支持外部蓝牙开关设备,测试时可以使用屏幕上的开关模拟
- Group Items 功能可以将多个元素合并为一个扫描单元,减少扫描步骤
- 自定义手势操作需要提供基于开关的替代方案
- App 的无障碍支持也影响 Siri Suggestions 和预测输入的准确性