大多数浏览器和
Developer App 均支持流媒体播放。
-
打造无障碍的空间体验
了解如何创建适用于所有用户的空间计算 App。与所有 Apple 平台一样,visionOS 专为辅助功能而设计:我们将分享如何重新构想旁白和指针控制等辅助技术,以及如何设计停留控制等功能来帮助用户以最适合自己的方式进行交互。了解视觉、运动、认知以及听觉辅助功能的最佳实践,帮助每位用户享受 visionOS 的沉浸式体验。
章节
资源
- Accessibility
- Diorama
- Improving accessibility support in your visionOS app
- Media Accessibility
- UIAccessibility
相关视频
WWDC23
WWDC22
WWDC21
WWDC20
WWDC19
-
下载
♪ 悦耳的器乐嘻哈 ♪ ♪ Dan Golden:大家好 我是来自 Accessibility 团队的 Dan 很高兴和我的同事 Drew 一起 向你介绍空间计算中的辅助功能 在本次讲座中 我会为你概述 一些该平台上的 辅助功能 接着 我会详细介绍 你可在 App 中打造哪些功能 来帮助盲人及视障人士 然后 我会把时间交给 Drew 他会向你介绍 空间计算中的运动、认知 以及听觉辅助功能 我们现在开始吧 我们设计的这个沉浸式平台 适用于所有用户 尽管空间计算体验的构建 总是包含令人惊叹的视觉特征 以及大量手势输入 但这并不意味着视力或身体运动 是参与该体验的必要条件 事实上 这些体验可能会对 盲人、视障人士、行动不便者 以及肢体残障人士 产生无比巨大的影响 例如 盲人可以 与现实世界交互 而无需看到显示屏上的内容 因此 在你构建 App 时 请务必考虑到用户的各种能力 以便每位用户 都能享受辅助功能带来的益处 在 Apple 我们坚信 使用科技是一项基本人权 并且该平台包括了 我们在第一代产品中 所推出的最全面的辅助功能列表 在这里 你将看到 你所熟知和喜爱的功能 例如 动态字体支持、增强对比度 以及朗读内容功能等 并且 我们还专门针对空间计算 重新构思了主要的辅助技术 我们对这些功能感到兴奋 作为开发者 你可以通过 确保所构建的体验 覆盖了所有用户来提供更多帮助 接下来 我们先来谈谈 如何在你的 App 中 为盲人或视障人士提供支持 在探讨视觉辅助功能时 我们需要考虑以下几点: 旁白支持、视觉设计以及动态效果 首先 我们来谈谈旁白支持 旁白是所有 Apple 平台 均提供的内置屏幕朗读器 并且我很高兴告诉你 我们也将其引入了该平台 Drew 和我一直在开发 一款非常有趣的 App 名为 Happy Beam 并且该 App 使用了 ARKit 和 RealityKit 在该 App 中 你可以用手比划心形手势 来让暴躁的云变开心 我们来看看 改进该 App 中旁白体验的一些方法 我们已经在 “设置”>“辅助功能” >“辅助功能快捷键”中 将旁白添加到辅助功能快捷键中 所以 我们只要连按三下侧边按钮 就可以打开或关闭旁白 这个工具在我们 测试 App 的辅助功能时十分有用 让我们打开 App 并连按三下侧边按钮 打开旁白 ♪ 轻柔的器乐 ♪ 旁白:Happy Beam 请选择让暴躁的云变开心的方式 Dan:在该平台上 旁白会根据不同手上 两个手指捏合的手势 来执行不同的操作 默认情况下 你可以捏合右手食指 来切换到下一个项目 ♪ 旁白:请使用双手 比划出心形 按钮 请使用两个手指捏合的手势 或兼容设备 按钮 Dan:如果需要切换到前一个项目 你则需要捏合右手中指 旁白:请使用双手 比划出心形 按钮 Dan:如果需要启用项目 捏合右手无名指 或左手食指即可 现在 我们已经熟悉了 旁白的部分基本控制方式 接下来 我们来探索一下 该 App 的其余功能 旁白:三、二、一 HAPPY BEAM 返回按钮 分数为 0 停止音乐 按钮 剩余 29 秒 暂停 按钮 Dan:看上去效果不错 由于该 App 使用 SwiftUI 进行构建 所以我们使用的大部分标准控件 均可访问 并且 我们也注意到需要 对剩余视图使用 SwiftUI 辅助功能修饰符 来确保向旁白 提供合适的辅助功能信息 想进一步了解更多信息 请查看我们 关于 SwiftUI 辅助功能的讲座 接下来 我们来看看 App 的 剩余部分 并了解一下如何与云互动 旁白:关闭 按钮 弹出窗口 App 位置栏 App 位置 -- App 位置 -- App 位置栏 Dan:这个声音表明 旁白无法找到 任何可进行交互的项目 所以旁白无法访问云 由于云是使用 RealityKit 生成的 因此 我们可以使用 RealityKit 中可用的新辅助功能组件 来解决这个问题 使用辅助功能组件 你可以在 RealityKit 实体上 指定辅助功能属性 其中 你可以配置 辅助功能的标签、值和特征 以及自定义转子、自定义内容 和自定义操作 同时 你还可以配置 系统辅助功能行为 例如可启用且可调整的操作 为了可以访问云 我们先来创建 一个新的辅助功能组件 并将 isAccessibilityElement 设置为 true 来告知辅助技术 云应该是可导航的 接着 我们来为云提供 button 特征 以便让切换控制及语音控制 等技术知道 云是可与用户交互的项目 同时 我们还会赋予其 playSound 特征 因为云在变开心时会发出声音 然后 我们会 使用 label 属性为云命名 并使用 value 来描述 云是处于暴躁还是开心的状态 每当你的 App 状态得到更新 你也需要确保更新辅助功能组件上的 相关属性 此处 在 isHappy 变量的 didSet 处理程序中 我们会使用一个方便属性 来更新云的 accessibilityValue 只要你使用了方便属性 辅助功能组件上的对应属性 也会相应得到更新 由于标签和值会作为 LocalizedStringResources 进行存储 所以其便可以使用 字符串字面量进行创建 但是 其会自动解析为你在运行时 提供的本地化值 最后 我会在 实体组件列表上对组件进行设置 让我们再来看一下 App 其中的云现在应该可以访问了 ♪ 旁白:App pl-- 云 暴躁 按钮 Dan: 太棒了! 现在我们可以导航到云 并且可以获取云的状态 旁白使用空间音频 来提示物体的位置 所以 我们试着用一个心形手势 来让其中一朵云变开心吧 ♪
这到底怎么回事? 我们刚刚向那朵云 做了那么多心形手势 但云就是没有变开心 这是因为启用旁白时 你的 App 默认不接收手势输入 此做法旨在确保你的 App 不会在他人执行旁白手势时 无意中执行操作 从而让用户可以进行安全探索 在该平台上 旁白引入了一个新的直接手势模式 启用该模式后 旁白不会处理标准手势 而是会让你的 App 直接处理手势输入 用户可以选择 在直接手势模式下 或是旁白默认交互模式下运行 App 并且每种模式都有 需要注意的辅助功能的考虑因素 我们先来谈谈 旁白默认交互模式 我们来添加一个激活操作 从而可以使用旁白来让云变得开心 为了实现这一点 我们会在 accessibilityComponent 的 systemActions 属性中 添加激活操作 接着 我们会订阅 RealityView 内部内容的 激活事件 并且 每当我们 在回调中接收到激活事件时 我们会更新 gameModel 来让相关云的状态也得到相应更新 我们再来看看添加操作之后的 App 旁白:App 位置-- 关闭 -- 云 暴躁 云 暴躁 Dan:太棒了! 现在 我们就可以 使用旁白让云变开心了 此外 AccessibilityComponent 还提供了其他的 API 例如自定义操作、自定义转子 以及自定义内容 这些出色的工具都可以 改进 App 内的辅助功能体验 想进一步了解更多信息 请查看相应主题下的讲座 接下来 我们来谈谈直接手势模式 这是一种同时使用平台上的旁白 与 App 进行交互的新方式 由于直接手势模式不支持 旁白的激活操作 所以我们需要为 我们即将使用的 手势输入交互提供反馈 我们首先从云出现时 发布描述云及其在世界中的位置的 通知开始 为了实现这一点 我们会使用 Announcement 类型 创建一个新的 AccessibilityNotification 并传入我们想要播放的字符串 接着在 Announcement 中 调用 post 函数 在空间体验中 提供可使用项目 及其位置的信息至关重要 所以 这是 App 中最重要的通知 并且 我们还会在心形手势得到识别 以及云从暴躁变为开心时 发布通知 始终告知旁白任何有意义的事件 来使其清楚当前正在发生什么 以及当前正在执行哪些交互操作 例如 在完全沉浸式 App 中 每当你进入新房间或新环境时 请确保将该内容变化告知旁白 并描述该世界中的任何可用新项目 同时 你还可以考虑 在执行操作时使用声音 Happy Beam 在云变开心后 所播放的声音 可以有效保持 App 的趣味性和空间感 即便我们无法看到云的视觉变化 我们最后再来看一下 App 在添加通知后的效果 在游戏开始后 我们可以捏三下左手食指 并保持 便可以启用直接手势模式 接着 我们使用 心形手势让云变开心 并获取所有交互的反馈 旁白:三、二、一 Happy Beam 在你的上方右前侧有 3 朵云 启用直接手势 按下侧边按钮进行操作-- 发射光束 ♪ 击中暴躁的云 收起光束 Dan:太棒了! 我们在交互执行时 收到了所有交互顺利执行的反馈 我们的 App 经过逐步改进 拥有了一些出色的旁白支持 但你还可以开发更多功能 来支持那些没有借助旁白 使用你 App 的视障人士 尤其在你构建自定义组件 和控件的时候 就和在其他 Apple 平台上一样 你需要确保 App 可以对 动态字体的变化作出反应 特别是针对辅助功能设置中提供的 最大字体 你需要检查你的 App 中是否存在 UI 在较大字体的情况下 垂直布局比水平布局效果更好 此外 你还需要确保 前景和背景颜色之间 至少具有四比一的对比度 想进一步了解更多信息 请查看 “让你的 App 具备视觉辅助功能”讲座 在空间体验中 你可以使用锚 来放置与其他锚点相关的内容 例如手或世界中的特定位置 你还可以将内容配置为 锚定到虚拟相机上 从而使其出现在显示屏的相同位置 尽管你可能很熟悉 其他 Apple 平台上 RealityKit 中的相机锚点 但是在该平台上 内容会在你看向四周时 随着头部的移动发生变化 从而这就可能会对视障人士 产生不同的影响 因此 你需要尽量避免使用头部锚点 并在使用时保持谨慎 这样 视障人士才能够更靠近内容 以便阅读或查看细节 此外 使用辅助功能中 缩放功能的用户 可能无法轻松将头部锚点内容 放置在变焦镜头中 因为变焦镜头也是以头部为锚点的 相反 你可以考虑使用世界锚点 或在延迟后缓慢移动内容 而针对需要使用头部锚点 这类极少数的情况 你需要确保内容是装饰性的 并且 重要的内容不应仅通过 头部锚定内容进行访问 始终为头部锚点提供替代方案 即便更改锚点是你 App 中 最主流的体验 SwiftUI 中新的环境变量 accessibilityPrefersHeadAnchorAlternative 以及 Accessibility 框架中的 AXPrefersHeadAnchorAlternative API 可以告诉你何时应该使用备用锚点 并且 你需要在 App 中使用 头部锚点的位置观察这些 API 我们已经在系统中采用了这些 API 默认情况下 控制中心在折叠状态下 以头部为锚点 在这里你可观察到 当你看向四周时 控制中心都会跟随你的视线
尽管该设计从各个位置 都可以轻松访问控制中心 但我们知道 该操作对某些用户而言 可能极为困难 我之前提到过 缩放也是以头部为锚点 该功能可以为视障人士 放大内容 在启用缩放或有用户表示 更喜欢头部锚点的替代方案时 控制中心就会在 Y 轴自由移动 在这里 你可以看到 当你抬起头时 变焦镜头会跟随头部移动 但是控制中心不会 你可以将控制中心 放置在变焦镜头内 然后与之进行交互 同时 注意 App 中 动态效果的使用也很重要 对于某些用户而言 尽管应用轻微的动态效果 也会使其感到晕眩 而且 佩戴耳机会为其 带来更为不适的体验 你需要避免在 App 中 对用户使用快速移动的动态效果 或是包含弹跳以及波浪式的动画 此外 缩放动画、 涉及多个轴线移动的动画、 旋转或转动效果 以及持续的背景效果 也应极力避免 你需要在启用减弱动态效果时 为这些类型的动画提供替代方案 你可以使用 SwiftUI 中的 accessibilityReduceMotion 环境变量来确认减弱动态效果 是否处于激活状态 在 UIKit 中 你可以使用 UIAccessibility. isReduceMotionEnabled 进行查询 同时借助相应的通知 来观察偏好设置的变化 如果你无法为 App 中的动态效果 找到合适的替代方案 你可以考虑使用交叉淡入淡出效果 此处展示的示例向你介绍了 如何在系统中使用减弱动态效果 请注意观察该胡德山环境中的水面 可以看到水面在背景中持续波动 当我们启用减弱动态效果 水面就会以静态的方式体现 波动效果 在这里 我们无需使用动态效果 即可以实现类似的视觉效果 以上就是关于如何改进 App 中 视觉辅助功能的全部介绍 但是在谈到运动、 认知以及听觉辅助功能时 你还需要考虑更多因素 关于这些内容 接下来 Drew 会为你带来更多介绍 Drew Haas:谢谢 Dan 讲得真好! 我是 Drew Hass 一名 Accessibility 团队的工程师 刚刚我们已经了解了一些 如何改进空间体验中视觉辅助功能的 有效方法 现在我还想与你分享 如何创建一款 App 使其包容影响运动交互功能、认知 以及听觉的残障人士 我们首先从运动开始 默认的输入系统 由手眼结合进行驱动 例如 你将眼睛看向按钮 并捏合双手 这样便可以发送选择事件 来激活按钮 但是 并不是所有人都可以执行 这种身体操作 我们的辅助功能可以为 具有眼部、手部或两者缺陷的用户 提供输入方式的替换方案 停留控制辅助功能可以让用户 在不使用双手的情况下 实现选择并与 UI 进行交互 停留控制支持轻点、滚动、 长按以及拖移等手势 你在设计 App 时 应包含 这些手势集合所具有的全部功能 从而避免将使用停留控制的 用户排除在外 你可以使用停留控制菜单 轻松实现手势模式的切换 从而可以让用户 在不降低效率的情况下 使用调节来操作设备 这种设计的目的在于 为用户提供顺畅的体验 即便其使用的是非默认输入 我们来看看如何 对 Happy Beam App 进行设计以支持多种输入 以便在使用停留控制时 实现完全操作 在启动 Happy Beam 后 玩家首先需要选择 让暴躁的云变开心的方式 在本次讲座前半部分 你了解了第一个选项: 将双手比作心形 然后将其瞄准云 第二个选项支持键盘 以及游戏控制器等 蓝牙配件 在使用这种输入方式时 快乐光束就会 通过心形炮台进行发射 并且 该炮台也可以响应 轻点和拖移手势 这就意味着 你可以单手玩游戏 并且 使用停留控制进行游戏的用户 能够使用炮台的全部功能 所以 你需要计划并设计 像 Happy Beam 这样 可以支持不同输入的 App 这样可以有效保证 你不会在无意之中排除部分用户 此外 还有一种辅助功能 可以与停留控制实现有效结合 该功能就是输入指针控制 这是我最喜欢的辅助功能之一 该功能可以转换输入体验 使用户可以使用不同的输入源 而不是眼睛来控制系统的焦点 虽然眼睛是默认设置 但在这里用户可以使用 头部位置、手腕位置以及食指 来改变系统焦点 由于指针控制可以改变输入信号 以跟随头部位置移动 所以 请务必记住 谨慎使用相机锚定内容 并且 这也是另一个你会倾向于 使用世界锚点 或为相机锚定内容 提供替代方案的原因 对停留控制和指针控制而言 无论是单独使用 还是将两者功能结合 都能为用户与设备的交互 带来巨大的灵活性 并且 这些功能可以满足 使用系统所需的动作要求 你需要为动作交互提供多种方案 因为你永远不知道 使用你 App 的用户患有哪种残疾 空间体验为与内容的交互 带来了多维度的新方法 切换控制具有新的菜单项 可用于调整世界空间中的相机位置 在这里 我们使用 具有切换控制的键盘 来激活新的相机位置修饰符 使用该操作可以 将你的空间位置下移 而无需你实际移动自己的身体 并非所有用户都能在其环境中 进行顺利或自由的移动 虽然切换控制 支持这些相机位置选项 但如果你创造的体验 需要用户以特定的方式 安置自己的位置 请务必提供这些体验之外的选项 接下来 我会谈谈认知辅助功能 以及如何支持 在学习、记忆以及信息处理方面 受到影响的残障人士 引导式访问是一种认知辅助功能 通过将系统限制在一个 App 中 来提高用户的专注度 该功能旨在将其他 App 置于后台、 移除可能会导致分心的装饰性 UI 以及抑制可能让用户离开当前体验的 硬件按钮事件 来将干扰降到最低 使用这种方式来调整系统 你可以轻松 帮助用户专注于当前任务 而不会出现分心 或轻易受到干扰的情况 想要进一步了解 有关如何使用引导式访问 以及如何实现自定义限制 API 请观看我去年的讲座 “创造无障碍的单一 App 模式体验” 你只需要遵循一些认知辅助功能的 最佳实践 便可以让每位用户 轻松使用你的 App 尤其是那些残障人士 部分用户可能还需要你 为他们降低 App 的复杂度 需要复杂手势的交互 对于部分用户而言 可能很难学习和保持 你可以使用类似 SwiftUI 等 Apple 的 UI 框架 来创造一致且熟悉的视觉体验 用户可以在短时间内 适应 App 操作 拥有舒适的体验 因为他们很可能在此之前已经使用过 由相同 UI 框架构建的其他 App 最后 你还需要让用户 沉浸式感受 并体验你所提供的一切 你没有必要让用户 匆匆完成一段体验 沉浸式内容可 以提高专注度和注意力 因此对于患有 感觉处理障碍的用户而言 该方法可以有效为其 创造舒适自如的环境 需谨记 并非所有用户 都能够以相同的速度处理信息 所以部分用户 可能需要一点额外的时间 来完成一段体验 最后 我还想分享一些 用于为失聪者或听障人士 提供访问信息和 适应环境的有效方法 使用音频和语音让用户 沉浸在空间体验中非常常见 但对于患有听力损失或 听觉处理障碍的用户而言 你可以做的最具影响力的事情 便是提供高质量字幕 来让他们获取内容 其中创造舒适阅读体验的 一种简便方式 是使用弹出式字幕 即一次呈现一个易于阅读的句子 来取代滚动字幕 由于后者是逐字呈现 因此长时间阅读过后 很容易造成阅读疲劳和晕眩感 你知道用户可以在设备上 自定义字幕的视觉外观吗? 字幕可自定义的内容十分广泛 你可以修改文字大小、字体、颜色 以及笔画轮廓或背景 使用这些选项 用户可以自定义其字幕 以便轻松进行观看和阅读 AVKit 和 AVFoundation 提供内置支持 可用于为你的 App 提供字幕 这些框架可以自动调整 字幕的外观和视觉样式 如果你没有使用 AVFoundation 这是因为你正在执行 自己的字幕系统 因此你有必要了解接下来的两个 API 第一个是 isClosedCaptioningEnabled API 使用该 API 你可以确认是否有用户 在辅助功能设置中 打开了隐藏式字幕 如果你的 App 存在单独的字幕设置 那么你应该使用该 API 来告知字幕的默认状态 这样 依赖字幕的用户 就可以立即获取字幕内容 第二个 API 位于 Media Accessibility 框架中 该框架允许 API 单独访问 每个样式属性 你只需要对这些样式进行确认 然后将其应用到字幕中 便可在整个系统中 创造一致的阅读体验 无论你选择哪种方式提供字幕 你都应该确立 适用于字幕质量的严格标准 字幕应该体现所有的音频内容 包括音乐和音效 同时 如果方向性对你的 App 至关重要 告知用户音频在空间中的来源 也会有所帮助 并且你只需要告知用户 “请记住 你最近的音源 就在你的身后” 令人印象深刻的辅助功能体验 总是源于对所有人 及其需求的仔细考量 你可以在实体上设置辅助功能属性 来为用户提供丰富的 RealityKit 体验 旁白、声音控制 以及切换控制等技术 为你 App 中的辅助功能提供了基础 保持随机应变 并为动作交互提供多种选择 正如我们在 Happy Beam 中 看到的那样 以包容所有玩家及其游戏方式 努力消除歧义 为患有认知障碍的用户 提供清晰且重点的内容 同时 对于音频体验中的字幕内容 给予足够的精力和重视 从而让失聪者或听障人士 也能享受你所创造的内容 如果你还不知道该从哪里开始 启用部分辅助功能 打开你的 App 开始体验吧! 亲自尝试这些功能 是你快速入门的有效方式 该平台为所有人设计 同时涉及了 Dan 和我今天分享的全部内容 现在你便能够创建辅助功能 以及极具包容性的空间体验 感谢你的观看! ♪
-
-
5:28 - Use AccessibilityComponent with RealityKit
var accessibilityComponent = AccessibilityComponent() accessibilityComponent.isAccessibilityElement = true accessibilityComponent.traits = [.button, .playsSound] accessibilityComponent.label = "Cloud" accessibilityComponent.value = "Grumpy" cloud.components[AccessibilityComponent.self] = accessibilityComponent // ... var isHappy: Bool { didSet { cloudEntities[id].accessibilityValue = isHappy ? "Happy" : "Grumpy" } }
-
8:04 - Add an activate action
var accessibilityComponent = AccessibilityComponent() accessibilityComponent.isAccessibilityElement = true accessibilityComponent.traits = [.button, .playsSound] accessibilityComponent.label = "Cloud" accessibilityComponent.value = "Grumpy" accessibilityComponent.systemActions = [.activate] cloud.components[AccessibilityComponent.self] = accessibilityComponent // ... content.subscribe(to: AccessibilityEvents.Activate.self, componentType: nil) { activation in handleCloudCollision(for: activation.entity, gameModel: gameModel) }
-
9:23 - Announce meaningful events and changes in context
AccessibilityNotification.Announcement("8 clouds in front of you").post()
-
13:15 - Provide alternatives to head anchored content
// SwiftUI @Environment(\.accessibilityPrefersHeadAnchorAlternative) private var accessibilityPrefersHeadAnchorAlternative // UIKit AXPrefersHeadAnchorAlternative() NSNotification.Name.AXPrefersHeadAnchorAlternativeDidChange
-
15:04 - Provide alternatives when Reduce Motion is enabled
// SwiftUI @Environment(\.accessibilityReduceMotion) private var accessibilityReduceMotion // UIKit UIAccessibility.isReduceMotionEnabled UIAccessibility.reduceMotionStatusDidChangeNotification
-
23:35 - Check whether captions are enabled
UIAccessibility.isClosedCaptioningEnabled UIAccessibility.closedCaptioningStatusDidChangeNotification
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。