在此 iOS 辅助功能教程中,了解如何使用 VoiceOver 和辅助功能检查器让应用更易于访问。
各行各业、各个年龄段和不同背景的人都使用智能手机应用程序,包括残疾人士。在设计您的应用时考虑到可访问性,可以帮助每个人使用它们,包括有视力、运动、学习或听力障碍的人。

在此 iOS 辅助功能教程中,您将改造现有的应用程序,使其更易于视障人士使用。在此过程中,您将学习如何:

  • 使用旁白。
  • 使用辅助功能检查器检查您的应用。
  • 使用 UIKit 实现可访问性元素。
  • 为残障人士打造更好的用户体验。

本教程需要 Xcode 12.4 和 Swift 5。

入门

在本教程中,您将使用一个名为Recipe的已经完成的应用程序,其中包含一个食谱列表及其难度级别。它还允许您评价您制作的菜肴的质量。

使用点击“下载资料”,下载开始使用所需的一切。在开始文件夹中打开Recipe.xcodeproj。

在设备上运行应用程序之前,您需要配置签名。

为此,请单击导航器中的Recipe项目,然后选择具有相同名称的目标。选择Signing & Capabilities选项卡,然后确保您选择了顶部的Debug。最后,从下拉列表中选择您的团队。

swift5 教程 swift5官方教程中文版_应用程序


了解食谱应用程序

现在,构建并运行该应用程序以熟悉其功能。

swift5 教程 swift5官方教程中文版_Inspector_02


根控制器是一个包含图像、描述和难度等级的食谱表视图。单击食谱以查看包含食谱成分和说明的大图。

为了让事情更令人兴奋,您还可以划掉清单上的项目,以确保您拥有所有必要的成分。如果你喜欢或讨厌你所做的,你可以切换喜欢/不喜欢表情符号。

食谱应用的幕后花絮

花几分钟时间熟悉开始项目中的代码。以下是一些亮点:

  • Main.storyboard包含应用程序的所有故事板场景。你会注意到所有的 UI 组件都是标准的 UIKit 控件和视图。它们已经可以访问,这使您的工作更轻松。
  • RecipeListViewController.swift管理根表视图,它显示所有可用配方的列表。它使用Recipe对象数组作为数据源。
  • Recipe.swift是代表食谱的模型对象。它包含用于加载您将在整个应用程序中使用的一系列食谱的实用方法。
  • RecipeCell.swift是根控制器的配方列表的单元格。它根据传递的Recipe模型对象显示配方的难度级别、名称和照片。
  • RecipeInstructionViewController.swift包含详细视图的控制器代码,它显示了菜肴的大图像以及其成分和烹饪说明。它具有UISegmentedControl在表格视图中的成分和说明之间切换的功能,使用InstructionViewModel.
  • InstructionViewModel.swift作为 的数据源RecipeInstructionsViewController。它包括成分和说明的描述以及复选框的状态信息。
  • InstructionCell.swift定义了一个包含标签和复选框的单元格,用于说明和成分列表。当您选中该框时,它会划掉文本。

现在您了解了该应用程序的工作原理,是时候考虑如何使其更易于访问了。

为什么是可访问性?

在开始使用代码之前,了解可访问性的好处很重要。

  • 无论您是使用KIF框架还是Xcode 中的UI 测试,设计您的应用程序的辅助功能都可以更轻松地编写功能测试。
  • 您还可以通过让更大的群体使用您的应用程序来扩大您的市场和用户群。
  • 如果您为任何政府机构工作,则需要实施508 合规性,其中规定所有用户都必须可以访问任何软件或技术。
  • 在您的应用中实现可访问性表明您愿意为每个用户付出更多努力,这是一件好事。
  • 知道您正在为某人的生活带来微小但显着的改变,这感觉真好!:]

相信吗?那么是时候了解 VoiceOver,这是一种为视觉障碍人士设计的辅助工具。

启用旁白

iOS 自带VoiceOver屏幕阅读工具,可帮助用户无需看屏幕即可与软件进行交互。它是专门为有视力问题的人设计的。

VoiceOver 可让视障用户听到屏幕上可见的内容并与之互动。VoiceOver 会响应手势,并以声音方式向用户传达屏幕上的内容或用户选择的内容。本质上,VoiceOver 是 UI 和用户触摸输入之间的链接。

使用 VoiceOver 的最快方法是在 iOS 设备上打开“设置”应用,选择“辅助功能”▸“辅助功能快捷方式”,然后选择“VoiceOver”。

swift5 教程 swift5官方教程中文版_swift5 教程_03


这会创建一个快捷方式,因此您可以在物理设备上连按三次主页按钮或侧边按钮,以打开和关闭 VoiceOver。

注意:除了 VoiceOver 之外,还有许多其他辅助功能,包括反转颜色、增加对比度、滤色器、减少白点、缩放、切换控制等等。在本教程中,您将主要关注 VoiceOver。
现在您已启用 VoiceOver,是时候尝试一下了。

如何使用旁白

VoiceOver 带有一些方便的手势预设,可让您轻松导航应用程序。以下是一些与 VoiceOver 一起使用的更常见的应用内手势:

  • 单击屏幕上的任意位置,VoiceOver 将从项目的辅助功能属性中大声读出识别信息。
  • 向左或向右滑动一次,VoiceOver 将选择下一个可见的辅助功能项并大声朗读。向右滑动向前和向下移动,而向左滑动则相反。
  • 向下滑动以逐个字母拼写重点项目。
  • 双击以选择焦点项目。
  • 三指向左或向右滑动可在页面视图中向前或向后导航。

有关 VoiceOver 手势的完整列表,请查看Apple 的 iPhone 上的学习 VoiceOver 手势。所以现在您知道 VoiceOver 的工作原理了——但是您的应用程序如何使用它呢?您将在下一步中对其进行测试。

使用 Recipe 应用程序尝试 VoiceOver

在物理设备上构建并运行,然后三次单击主页按钮以打开 VoiceOver。向左和向右滑动以浏览食谱列表。VoiceOver 从左上角到右下角读取元素。它以标题名称开头,后跟每个配方的名称和相关图像的名称。

但是 VoiceOver 体验存在一些问题:

  1. 图像不是每个单元格中图像视图的有用描述。你知道有一个图像,但不知道它是什么。
  2. VoiceOver 没有说明每个菜谱的难度级别,因此此功能对于有视觉障碍的人来说毫无用处。

现在您已经确定了问题区域,您可能想要立即着手修复它们。但在此之前,您需要了解一些辅助功能的工作原理。

可访问性属性

辅助功能属性是您必须实现以支持辅助功能的核心组件。这些属性为 VoiceOver 提供有关您应用中元素的信息,以便 VoiceOver 可以向您的用户大声朗读该信息。如果未正确配置,VoiceOver 将无法提供有关您的应用程序的必要详细信息。

一个可访问性属性有五个属性:

  1. Label标签:一种识别控件或视图的简洁方式。一些例子是后退按钮和配方图像。
  2. Traits特征:这些描述元素的状态、行为或用法。例如,可能会选择一个按钮特性。
  3. Hint提示:描述一个元素完成的动作。例如:显示配方详细信息。
  4. Frame大小框架 : 屏幕中元素的框架,格式为CGRect. VoiceOver 朗读CGRect.
  5. Value值:元素的值。例如,对于进度条或滑块,当前值可能为:5 out of 100。

大多数 UIKit 组件都为您预设了这些属性;您只需要提供详细信息即可改善用户体验。如果您创建自定义控件,则必须自己提供大部分属性。

注意:Recipe 应用程序使用标准 UIKit 视图和控件,这些视图和控件已经可以访问,并且最多需要修改属性字符串。对于具有自定义元素的项目,请务必阅读我们的iOS 辅助功能教程:使自定义控件可访问教程。

所以现在您知道 VoiceOver 从哪里获取它提供给用户的信息,是时候了解一个新工具来帮助您查找和修复应用程序中的辅助功能弱点:辅助功能检查器。

使用辅助功能检查器

如果您正在改造应用程序以使其更易于访问,则查找弱点既耗时又容易出错。幸运的是,有一个名为Accessibility Inspector的工具可以提供帮助,它执行以下操作:

  • 运行您的应用程序并查找常见的可访问性问题。
  • 让您在检查模式下检查 UI 元素的可访问性属性。
  • 无需离开您的应用程序即可提供辅助功能元素的实时预览。
  • 支持所有平台,包括 macOS、iOS、watchOS 和 tvOS。

在对食谱使用辅助功能检查器之前,请查看该工具。首先,通过导航到Xcode ▸ Open Developer Tool ▸ Accessibility Inspector在 Xcode 菜单中打开它。

swift5 教程 swift5官方教程中文版_应用程序_04


Accessibility Inspector检查员应该看起来像这样:

swift5 教程 swift5官方教程中文版_应用程序_05


在目标选择器可以让你选择你想检查的设备。这可能是您的 MacBook Pro、iOS 设备或您的模拟器。

辅助功能元素的实时预览让您可以直接在模拟器中进行测试。由于实时预览比收听 VoiceOver 更快,因此您将在此 iOS 辅助功能教程中完成大部分工作。

在模拟器中构建并运行,并将 Accessibility Inspector 目标更改为您的模拟器:

swift5 教程 swift5官方教程中文版_辅助功能_06


现在您已经打开了该工具,您可以查看它的一些最有用的功能。

使用检查指针

选择检查指针(在检查器 UI 中看起来像一个十字准线)类似于在您的设备上启用 VoiceOver。当您激活指针时,您可以将鼠标悬停在任何 UI 元素上以检查其属性。通过按下按钮直接与模拟器交互将停用检查指针。

检查详细信息窗格包含查看应用程序中的辅助功能属性并与之交互所需的一切:

  • Basic:显示当前突出显示的元素的属性属性。
  • Actions操作:让您执行诸如点击按钮或滚动视图之类的操作。按此窗格中的执行按钮将对您的目标执行操作。
  • Element元素:显示当前项目的类、地址和控制器。在撰写本文时,它并不能始终如一地工作。
  • Hierarchy:显示元素的视图层次结构,更容易理解复杂的视图。

swift5 教程 swift5官方教程中文版_swift5 教程_07

在 Xcode 中使用 Quicklook 检查音频

Xcode 11在顶部Quicklook部分的“检查详细信息”窗格中有一项新功能,允许您在 Xcode 中模拟您在设备上听到的音频。这意味着您可以在不需要实际设备的情况下检查用户在使用您的应用程序时听到的内容。

当应用程序在模拟器中运行时按下播放按钮,让辅助功能检查器循环浏览应用程序并聆听它大声描述每个元素。

如果您更喜欢手动单步执行每个元素,您可以按下“暂停”按钮或按下Quicklook部分中的“音频”按钮。按前进或后退按钮以您自己的步调逐步浏览每个组件。

swift5 教程 swift5官方教程中文版_辅助功能_08


使用此功能比在设备上运行应用程序和使用 VoiceOver 更快,尤其是在开发过程中。与往常一样,您还希望在真实设备上测试您的应用程序及其所有辅助功能。

突出检查员审计的问题

Inspector Audit 最有用的功能之一是它的审计功能,它会向您发出有关应用程序中可访问性问题的警告。要试用此功能,请确保模拟器仍在运行并且您在配方列表中。在检查器中,单击Audit图标,然后单击Run audit。

你会看到检查器给出了几个警告,包括你的一些元素缺乏描述。

swift5 教程 swift5官方教程中文版_Inspector_09


当您单击警告时,Xcode 会突出显示模拟器中以及 Inspector Audit 屏幕底部的相关元素。

在这种情况下,与单元格关联的图像视图没有描述。这意味着 VoiceOver 将无法向您的读者描述它们。

单击Suggest Fixes图标(看起来像圆圈中的问号)以查看其中一个警告,检查员将提供有关如何解决问题的建议。稍后您将根据这些建议采取行动。

swift5 教程 swift5官方教程中文版_Accessibility_10


单击眼睛图标以拍摄应用程序的快照。这对于需要创建准确错误报告的质量保证人员来说非常有用。

swift5 教程 swift5官方教程中文版_Accessibility_11


您可以在检查器中找到一些更有用的辅助功能设置。接下来,您将快速了解这些功能。

其他检查器设置

尽管它们不在本教程的范围内,但很高兴知道辅助功能检查器还允许您测试以下辅助功能设置:

  • 反转颜色
  • 增加对比度
  • 降低透明度
  • 减少运动
  • 更改字体大小

您不再需要使用“设置”应用来启用这些功能。Accessibility Inspector 目前仅提供这五个选项,但 Apple 计划在未来添加更多选项。

swift5 教程 swift5官方教程中文版_Inspector_12


辅助功能检查器可在测试您的应用程序时节省时间。但是请记住,您仍应手动测试 VoiceOver 以尝试实际的用户体验。这最后一步可帮助您发现检查员遗漏的任何问题。

现在您已经了解了辅助功能检查器的功能,是时候开始使用您的应用程序了。

使食谱应用程序可访问

当您使用 VoiceOver 在您的设备上测试您的应用程序时,您注意到图像的描述不是很有用。该审计工具展示了原因所在:在图像视图没有一个可访问的标签。你现在要解决这个问题。

在 Xcode 中,打开RecipeCell.swift并将以下代码添加到文件底部:

// MARK: Accessibility 

extension  RecipeCell  {
   func  applyAccessibility ( _  recipe : Recipe ) {
     // 1 
    foodImageView.accessibilityTraits = .image
     // 2 
    foodImageView.accessibilityLabel = recipe.photoDescription 
  } 
}

此代码根据Recipe单元格的对象填充缺少的辅助功能属性。这是它的工作原理:

  1. accessibilityTraits采用表征可访问性元素的特征掩码。在这种情况下,.image表示它是一个图像。
  2. 您accessibilityLabel用来描述 VoiceOver 中的元素。在这里,它被设置为recipe.photoDescription,这是一个描述图像内容的字符串。

现在,您也想将其应用到未来的食谱中。configureCell(_:)在RecipeCell课堂上寻找。将以下行添加到该方法的末尾:

applyAccessibility(recipe)

每次创建单元格时,此代码都会使用配方对象中的属性将可访问性属性应用于图像。

建立和您的设备上运行,并启用VoiceOver会与三个水龙头上的主页按钮。测试配方列表以查看图像描述是否更有意义。

好多了!您现在听到的不是简单地听到没有提供具体细节的“图像”,而是对图像的完整描述。用户现在可以将食物可视化,而不是因不知道图像是什么而感到沮丧。

在应用程序仍在模拟器中运行的情况下,再次运行辅助功能检查器并导航到配方列表。确保清除检查器中的所有警告并点击Run Audit。

swift5 教程 swift5官方教程中文版_Accessibility_13


WOOt — 不再有描述警告!成功向图像添加描述后,此视图的核心现在可以完全访问。

现在,是时候让食谱的难度级别变得可访问了。

转换难度标签

在辅助功能检查器中,您会看到可能无法访问的文本警告,它告诉您难度标签对于有视觉障碍的用户是不可见的。要解决这些问题,您需要使标签可访问并使用有意义的描述更新其属性。

对于下一步,转到RecipeCell.swift并将以下内容添加到末尾applyAccessibility(_😃:

// 1
difficultyLabel.isAccessibilityElement = true
// 2
difficultyLabel.accessibilityTraits = .none
// 3
difficultyLabel.accessibilityLabel = "Difficulty Level"
// 4
switch recipe.difficulty {
case .unknown:
  difficultyLabel.accessibilityValue = "Unknown"
case .rating(let value):
  difficultyLabel.accessibilityValue = "\(value)"
}

以下是有关此代码功能的更多详细信息:

  1. isAccessibilityElement是一个标志,当 时使该项目对辅助功能可见true。对于大多数 UIKit 类,默认是true,但对于 UILabel 是false。
  2. accessibilityTraits有助于表征可访问性元素。由于您不需要任何交互,因此您将其设置为没有特征。
  3. 接下来,您让 VoiceOver 简明地识别此标签的意图。Difficulty Level让用户确切地知道他们正在处理什么。
  4. VoiceOver 会将 阅读accessibilityValue作为标签说明的一部分。在这里设置难度级别使这个元素更有用。

在物理设备上构建并运行您的应用程序,三次点击主页按钮以启用 VoiceOver 并在食谱列表中滑动。
当您滚动浏览不同的辅助功能元素时,VoiceOver 会读取每个单元格的完整说明,包括难度级别。

检查警告

每次您公开一个新的可访问性元素时,就像您在此处使用难度级别所做的那样,您应该再次运行审核。

启动辅助功能检查器(如果它尚未运行)。在您的设备或模拟器上运行应用程序并相应地设置检查器目标。现在,选择审计切换按钮并点击Run audit。

swift5 教程 swift5官方教程中文版_Accessibility_14


出现的警告更少!其余的是关于不支持动态文本的标签。你接下来会解决这些问题。

swift5 教程 swift5官方教程中文版_Accessibility_15


它告诉您使用 UIfont 首选字体并设置adjustsFontForContentSizeCategory为 true。你现在就去做。

在RecipeCell.swift 的最底部添加以下代码applyAccessibility(_😃:

dishNameLabel.font = .preferredFont(forTextStyle: .body)
dishNameLabel.adjustsFontForContentSizeCategory = true

difficultyLabel.font = .preferredFont(forTextStyle: .body)
difficultyLabel.adjustsFontForContentSizeCategory = true

这会将设置preferredFont为一种body样式,这意味着 iOS 会将文本设置为文档正文的样式。大小和字体的细节取决于辅助功能设置。adjustsFontForContentSizeCategory指示当用户更改文本内容大小时字体应自动更新。

借助辅助功能检查器,可以轻松测试您的应用程序如何处理调整字体大小。

与辅助功能检查器一起构建并运行配方应用程序。再次运行审计,所有警告都应该消失了。

使文本动态

审核员警告您,您错过了让每个人都可以使用您的应用程序的重要步骤:动态文本。这是辅助功能的一个重要功能,允许有部分视力障碍的用户增加字体大小以提高可读性。您的应用当前使用的非动态字体不允许这样做。

单击“修复建议”图标以查看审核员的建议:

swift5 教程 swift5官方教程中文版_swift5 教程_16

测试一些其他选项

导航到检查器中的“设置”切换按钮并尝试使用一些工具:

反转颜色以使用此辅助功能预览您的界面外观。这对于对光敏感、视力不佳以及在某些情况下有色盲的人很有用。

您还可以为喜欢较大字体的用户实时测试动态字体大小的变化。

当您测试您的应用程序时,它可能看起来很像这样:

swift5 教程 swift5官方教程中文版_辅助功能_17


检查器使测试可访问性案例变得容易。由此,您可以看出食谱列表对于有视力障碍的用户来说效果很好。

转换配方详细信息屏幕

现在您已经处理了食谱选项列表,您想看看当用户单击其中一个食谱时会发生什么。在您的设备上运行该应用程序,启用 VoiceOver 并查看详细信息视图。这听起来像这样:

详细视图中的 VoiceOver 交互存在一些问题:

左箭头按钮不是导航的好描述。用户如何知道按钮的作用?
表情符号面部状态是:心形眼睛和困惑的脸。这些解释会让任何用户感到困惑!
当用户选择一个复选框时,它会显示icon empty,这并没有太多解释。
在每种情况下,重要的是解释控件的状态意味着什么,而不是它的外观。后退按钮比左箭头按钮更清晰。喜欢和不喜欢简洁地解释表情符号。接下来您将进行这两项更改。

要更改导航,请打开RecipeInstructionsViewController.swift并将以下内容添加到viewDidLoad, 之后assert(recipe != nil):

backButton.accessibilityLabel =  "back" 
backButton.accessibilityTraits = .button

VoiceOver 现在显示后退按钮,而不是向左箭头按钮。

现在,进入表情符号。在同一个文件中,将 的内容替换isLikedFood(_:)为以下内容:

if liked {
  likeButton.setTitle("😍", for: .normal)
  likeButton.accessibilityLabel = "Like"
  likeButton.accessibilityTraits = .button
  didLikeFood = true
} else {
  likeButton.setTitle("😖", for: .normal)
  likeButton.accessibilityLabel = "Dislike"
  likeButton.accessibilityTraits = .button
  didLikeFood = false
}

对于 Like 和 Dislike 模式,您添加了一个accessibilityLabel明确按钮的功能。您还设置accessibilityTraits将其标识为按钮,以便用户知道他们可以如何与其交互。

在设备上构建并运行并启用VoiceOver。使用 VoiceOver 导航到详细配方屏幕以测试您对视图顶部按钮的更改。
现在,这些功能中的每一个都有清晰、简短的描述,可帮助用户理解他们的意图。好多了!

改进复选框

最后一个问题是清单。对于每个复选框,VoiceOver 当前状态图标为空,然后是配方说明。这根本就不清楚!

要更改此设置,请打开InstructionCell.swift并查找shouldStrikeThroughText(_😃. 将整个if strikeThrough语句替换为以下内容:

// 1
checkmarkButton.isAccessibilityElement = false

if strikeThrough {
  // 2
  descriptionLabel.accessibilityLabel = "Completed: \(text)"
  attributeString.addAttribute(
    NSAttributedString.Key.strikethroughStyle, 
    value: 2, 
    range: NSRange(text.startIndex..., in: text))
} else {
  // 3
  descriptionLabel.accessibilityLabel = "Uncompleted: \(text)"
}

下面是这段代码的作用:

关闭复选标记按钮的辅助功能,以便 VoiceOver 将其作为一个单元而不是两个不同的辅助功能元素读取。
在accessibilityLabel该说明现在使用硬编码字符串"Completed"后面的文本。这提供了一次访问标签的所有必要信息。
与已完成代码一样,如果用户将项目标记为未完成,则"Uncompleted"在标签描述之前添加。
再次构建并运行应用程序,看看它听起来如何。这将是您用户耳中的音乐。:]

然后去哪儿?

您可以使用本教程顶部或底部的下载材料按钮下载项目的完整版本。

在此 iOS 辅助功能教程中,您了解了 VoiceOver。您通过滚动每个可访问的元素并亲自测试用户体验来执行手动审核。然后,您使用 Accessibility Inspector 执行审核、查看可访问性元素值并执行实时动态更改以反转颜色或更改字体大小。

现在,您拥有了使您的应用程序更易于访问的必要工具。知道你会对某人的生活产生积极的影响是值得的。