Create accessible experiences for watchOS
Accessibility 进阶 20m

为 watchOS 打造无障碍体验

Create accessible experiences for watchOS

2021年6月9日

在 Apple 官方观看视频

一句话判断

watchOS 8 的新无障碍 API 让你的 Apple Watch App 能服务于更多用户——双指捏合手势、改进的 VoiceOver 和 AssistiveTouch 都是免费获得的特性,前提是你正确使用了 SwiftUI。

这场 Session 讲了什么

Session 聚焦 watchOS 8 中新增和改进的无障碍特性。Apple Watch 作为穿戴设备,无障碍的实现方式和 iOS 有显著区别——屏幕更小、交互方式更受限、用户可能只用一只手操作。

watchOS 8 新增了 AssistiveTouch,让上肢不便的用户可以通过握拳和捏合手势控制 Apple Watch,不需要触碰屏幕。Session 演示了如何确保你的 App 对这些手势操作友好——关键是在自定义控件中正确设置 accessibility traits 和 actions。

VoiceOver 在 watchOS 8 中也做了改进,包括更好的列表项朗读和对 SwiftUI 组件的更完整支持。Session 还介绍了如何用 Accessibility Inspector 测试 watchOS App 的无障碍特性。

值得深挖的点

AssistiveTouch 对自定义控件的要求

AssistiveTouch 通过手势识别模拟触摸操作,但它依赖控件的 accessibility 信息来决定焦点顺序和可操作区域。如果你的自定义 SwiftUI 视图没有设置 accessibilityLabelaccessibilityAddTraits(.isButton),AssistiveTouch 用户就无法”看到”或”点击”这个控件。对于 watchOS 上大量使用自定义绘制的表盘和复杂功能来说,这个问题尤其突出。

VoiceOver 的列表体验

watchOS 的列表通常是垂直滚动的短列表。VoiceOver 在朗读列表时,如果每个列表项没有有意义的 label,用户听到的是一堆无意义的描述。Session 建议为列表项设置完整的 accessibility label,包含关键信息(比如”心率 72 次/分,正常范围”而不是只读”72”)。

代码片段

为自定义控件添加无障碍支持

// 自定义的圆形进度指示器
struct CircularProgressView: View {
    let progress: Double
    let label: String
    
    var body: some View {
        Circle()
            .trim(from: 0, to: progress)
            .fill(Color.blue)
        // 关键:为自定义绘制添加无障碍信息
            .accessibilityLabel(label)
            .accessibilityValue("\(Int(progress * 100))%")
            .accessibilityAddTraits(.isStaticText)
    }
}

让列表项对 VoiceOver 友好

// 健康数据列表
List(healthItems) { item in
    HStack {
        Image(systemName: item.icon)
        VStack(alignment: .leading) {
            Text(item.title)
            Text(item.value)
                .foregroundColor(.secondary)
        }
    }
    // 自定义无障碍标签,提供完整信息
    .accessibilityElement(children: .ignore)
    .accessibilityLabel("\(item.title): \(item.value), \(item.status)")
    .accessibilityAddTraits(.isButton)
    .accessibilityAction {
        selectedItem = item
    }
}

响应 AssistiveTouch 手势

// 为可操作元素添加手势支持
struct ActionButton: View {
    let title: String
    let action: () -> Void
    
    var body: some View {
        Button(action: action) {
            Text(title)
                .font(.headline)
        }
        // 确保按钮对 AssistiveTouch 可见
        .accessibilityLabel(title)
        .accessibilityAddTraits(.isButton)
        // 自定义 accessibility action
        .accessibilityAction(named: "执行 \(title)") {
            action()
        }
    }
}

最佳实践

开发流程: 在开发 watchOS App 时,从一开始就在模拟器中打开 VoiceOver 测试。每个交互界面都应该能用 VoiceOver 完成完整操作流程。在 Accessibility Inspector 中检查是否有缺失的 label 或 trait。

设计阶段: watchOS 的 UI 元素要足够大(至少 44pt 点击区域),控件间距要足够(至少 8pt),让 AssistiveTouch 的手势识别更准确。避免纯颜色传达信息——添加文字或图标作为辅助。

还有什么值得关注

  • Accessibility Inspector 在 Xcode 13 中支持直接预览 watchOS App。
  • SwiftUI 的 accessibilityHidden(true) 可以隐藏装饰性元素,避免 VoiceOver 朗读无意义内容。
  • watchOS 8 的旁白(VoiceOver)支持更多语言的朗读。
WWDC 2021