欢迎光临散文网 会员登陆 & 注册

SwiftUI学习100天(Day74 - 项目 15,第一部分)

2023-03-19 12:37 作者:爱上树の蜗牛  | 我要投稿

原创链接:https://www.hackingwithswift.com/100/swiftui

以下内容仅供学习参考:

我们今天有一个新技术项目,这次的重点是你可能甚至没有考虑过的事情:可访问性。这是衡量我们的应用程序可以被具有不同访问需求的人使用的程度的指标——他们可能需要更大的文本,他们可能需要我们避免使用某些颜色以帮助他们清楚地看到事物,他们可能需要我们的 UI 被读出,等等。

太多的开发人员完全忽视了可访问性的重要性,这导致应用程序对很多人来说完全不透明。苹果 iPod 的创造者托尼·法德尔 (Tony Fadell) 曾说过:“你的定义取决于你做了什么,也取决于你没有做什么。”

当然, 你可以跳过辅助功能,而 90% 的人不会注意到,但你是否希望由它来定义?我敢打赌答案是否定的。

今天你有四个主题需要完成,你将在其中了解辅助功能标签、值、提示等。

辅助功能:简介

让你的应用程序易于访问意味着采取措施确保每个人都可以充分使用它,无论他们的个人需求如何。例如,如果他们是盲人,那么你的应用程序应该与系统的 VoiceOver 系统配合良好,以确保你的 UI 可以流畅地阅读。

SwiftUI 免费为我们提供了大量的功能,因为它的布局系统自然地VStackHStack形成了视图流。然而,它并不完美,任何时候你可以添加一些额外的信息来帮助 iOS 辅助功能系统,它可能会有所帮助。

通常,测试你的应用程序的最佳方式是启用 VoiceOver 支持并在真实设备上运行该应用程序——如果你的应用程序与 VoiceOver 配合得很好,那么你很可能已经远远领先于 iOS 应用程序的平均水平。

无论如何,在这个技术项目中,我们将研究一些无障碍技术,然后研究我们之前制作的一些项目,看看它们如何升级。

现在,请使用 App 模板创建一个新的 iOS 应用程序。你应该在真实设备上运行这个项目,这样你就可以真正启用 VoiceOver。

致谢:我非常感谢 Robin Kipp 在准备本章时提供的帮助——他写了一些关于他希望看到的有关可访问性的详细建议,并为我提供了一些很好的例子,说明这将如何影响他自己的个人使用。


使用有用的标签识别视图

在这个项目的文件中,我放置了四张从 Unsplash 下载的图片。Unsplash 文件名由图片 ID 和摄影师姓名组成,因此如果将它们拖到资产目录中,你会看到它们的名称如“ales-krivec-15949”等。这本身不是问题,事实上我认为这可能是记住资产来源的一种有用方式。但是,它确实给屏幕阅读器带来了问题。

要开始使用 VoiceOver,我们将创建一个简单的视图,该视图随机循环显示资产目录中的四张图片。将ContentView结构体修改为

这没有什么复杂的,但它已经有助于说明两个严重的问题。

如果你尚未在 iOS 设备的“设置”应用中启用 VoiceOver,请立即启用:“设置”>“辅助功能”>“VoiceOver”,然后将其打开。或者,你可以随时激活 Siri 并要求启用或禁用 VoiceOver。

重要提示:紧接在 VoiceOver 开关下方的是有关如何使用它的说明。你习惯的常规点击和滑动不再以相同的方式起作用,因此请阅读这些说明!

现在在你的设备上启动我们的应用程序,然后尝试在图片上点击一次以将其激活。如果你仔细聆听 VoiceOver,你应该会听到两个问题:

  1. 读出“Kevin Horstmann 一四一七零五”不仅对用户没有帮助,因为它根本没有描述图片,而且实际上令人困惑——一长串数字弊大于利。

  2. 读完上面的字符串后,VoiceOver 会说“image”。这是真的,它是一个图像,但它也充当一个按钮,因为我们添加了一个onTapGesture()修饰符。

这些问题中的第一个是 SwiftUI 试图为我们提供开箱即用的明智行为的副作用:当给定图像时,它会自动使用图像的文件名作为要读出的文本。

我们可以通过附加两个修饰符来控制 VoiceOver 为给定视图读取的内容:.accessibilityLabel().accessibilityHint()。它们都接受包含我们想要的任何内容的文本,但它们有不同的用途:

  • 标签会立即被阅读,并且应该是切中要害的一小段文字。如果这个视图从用户数据中删除一个项目,它可能会说“删除”。

  • 提示会在短暂的延迟后被读取,并且应该提供有关视图用途的更多详细信息。例如,它可能会说“从你的收件箱中删除一封电子邮件”。

标签正是我们解决第一个问题所需要的,因为这意味着我们可以保留图像名称不变,同时仍然让 VoiceOver 读出对用户有帮助的内容。

首先,将第二个图像描述数组添加为 ContentView的属性

现在将此修改器附加到图像上:

这允许 VoiceOver 读取正确的标签,而不管出现什么图像。当然,如果你的图像不是随机变化的,你可以直接在修改器中输入标签。

第二个问题是图像被识别为图像。这是不言而喻的事实,但它也无济于事,因为我们已将点击手势附加到它,因此它实际上是一个按钮。

我们可以使用另一个修饰符.accessibilityAddTraits()解决第二个问题。这让我们可以向 VoiceOver 提供一些额外的幕后信息来描述视图是如何工作的,在我们的例子中,我们可以通过添加这个修饰符来告诉它我们的图像也是一个按钮:

如果你愿意,你也可以删除图像特征,因为它并没有真正增加太多:

通过这些更改,我们的 UI 工作得更好:VoiceOver 现在可以读取图像内容的有用描述,并且还让用户意识到图像也是一个按钮。


隐藏和分组辅助功能数据

如果你花几分钟与活跃的 VoiceOver 用户相处,你会很快学到两件事:他们非常擅长在用户界面中导航,而且他们还经常将阅读速度设置得非常快——比你我使用的快得多.

在设计我们的 UI 时,将这两件事都考虑进去很重要:这些用户不仅仅是出于好奇而尝试 VoiceOver,而是依赖 VoiceOver 来访问你的应用程序的 VoiceOver 高级用户。因此,确保我们的 UI 尽可能消除混乱非常重要,这样用户就可以快速浏览它,而不必听 VoiceOver 阅读无用的描述。

除了设置标签和提示之外,我们还可以通过多种方式控制 VoiceOver 读出的内容。我特别想关注三个方面:

  • 将图像标记为对 VoiceOver 不重要。

  • 从无障碍系统隐藏视图。

  • 将多个视图组合为一个。

所有这些都是简单的更改,但它们会带来很大的改进。

例如,我们可以通过使用Image(decorative:). 无论是简单的要点还是应用程序吉祥物角色的动画,它实际上并没有传达任何信息,因此Image(decorative:)告诉 SwiftUI 它应该被 VoiceOver 忽略。

像这样使用它:

这使得 VoiceOver 可以访问图像,如果它具有一些重要的特征,例如.isButton- 当它突出显示时它会说“按钮”,并且如果我们附加一个有效的点击手势 - 但它不会读出图像的文件名作为自动 VoiceOver 标签。如果你随后添加将被读取的标签或提示。

如果你想更进一步,你可以使用.accessibilityHidden()修饰符,它使任何视图对可访问性系统完全不可见:

使用该修改器,图像对 VoiceOver 不可见,无论它具有什么特征。显然,只有当所讨论的视图确实没有添加任何内容时,你才应该使用它——如果你将视图放置在屏幕外,以至于用户当前看不到它,你也应该将它标记为 VoiceOver 不可访问。

从 VoiceOver 隐藏内容的最后一种方法是通过分组,这让我们可以控制系统如何读取相关的多个视图。作为示例,请考虑以下布局:

VoiceOver 将其视为两个不相关的文本视图,因此它会根据用户的选择显示“你的分数是”和“1000”。这两者都没有帮助,这就是.accessibilityElement(children:)修饰符的用武之地:我们可以将它应用于父视图,并要求它将子元素组合成一个单一的可访问性元素。

例如,这将导致两个文本视图一起阅读:

当子视图包含单独的信息时,这非常有效,但在我们的例子中,子视图确实应该作为一个单独的实体来阅读。因此,这里更好的解决方案是使用.accessibilityElement(children: .ignore)子视图对 VoiceOver 不可见,然后向父视图提供自定义标签,如下所示:

值得尝试这两种方法,看看它们在实践中有何不同。使用.combine在两段文本之间添加一个停顿,因为它们不一定设计为一起阅读。使用.ignore自定义标签意味着可以一次性阅读所有文本,并且更加自然。

提示: .ignore children的默认参数,因此你可以获得与.accessibilityElement(children: .ignore)仅使用 .accessibilityElement()相同的结果


读取控件的值

默认情况下,SwiftUI 为其用户界面控件提供 VoiceOver 读数,虽然这些通常很好,但有时它们只是不符合你的需要。在这些情况下,我们可以使用accessibilityValue()修饰符将控件的值与其标签分开,但我们也可以使用指定自定义滑动操作accessibilityAdjustableAction()

例如,你可以构建一个视图来显示由各种按钮控制的某种输入,例如自定义步进器:


通过点击交互,这可能会按照你想要的方式工作,但它并不是 VoiceOver 的绝佳体验,因为每次点击其中一个按钮时,所有用户都会听到“增加”或“减少”。

要解决此问题,我们可以通过使用accessibilityElement()accessibilityLabel()将我们VStack组合在一起,然后添加accessibilityValue()accessibilityAdjustableAction()修饰符以使用自定义代码响应滑动,从而为 iOS 提供有关如何处理调整的特定说明。

可调整的动作为我们提供了用户滑动的方向,我们可以随心所欲地做出回应。有一个附带条件:是的,我们可以在递增和递减滑动之间进行选择,但我们还需要一种特殊的默认情况来处理未知的未来值——Apple 保留在未来添加其他类型调整的权利。

这是它在代码中的样子:

这让用户可以选择整个VStack来读出“Value: 10”,然后他们可以向上或向下滑动来操纵值并只读出数字——这是一种更自然的工作方式。


SwiftUI学习100天(Day74 - 项目 15,第一部分)的评论 (共 条)

分享到微博请遵守国家法律