为什么无障碍功能不只是打勾,而是您应用的超能力
\n\n想象一下:您创建了一个很酷的应用。漂亮的界面、闪电般的动画、完美的Swift代码。您为此感到自豪。但突然发现15%的用户无法使用它。对他们来说,按钮太小,文字与背景融为一体,VoiceOver“朗读”的菜单混乱不堪。熟悉吗?
\n\n无障碍功能不是“强制任务”,也不是“为了打勾而做”。它关乎包容性、关怀,而且重要的是,关乎商业利益。iOS拥有一个强大的框架,可以让应用适应视力、听力、行动障碍以及认知特殊需求的人群。而Swift为我们提供了所有工具,让这一切优雅地实现。
\n\n在本文中,我们不会进行枯燥的讲解。我们将分析具体的代码示例,您可以立即应用到项目中。开始吧!
\n\nVoiceOver:如何“教会”应用介绍自己
\n\nVoiceOver是iOS内置的屏幕朗读器。它会“朗读”屏幕上的一切:文字、按钮、手势。但如果开发者没有准备好界面,VoiceOver可能会变得混乱。让我们来解决这个问题。
\n\n基本设置:accessibilityLabel 和 accessibilityTraits
\n\n帮助VoiceOver的最简单方法是设置元素的标签和类型。例如,您有一个心形图标的按钮。没有标签时,VoiceOver只会说“按钮”,而有标签时,它会说“添加到收藏”。
\n\nlet favoriteButton = UIButton(type: .system)\nfavoriteButton.setImage(UIImage(systemName: "heart"), for: .normal)\nfavoriteButton.accessibilityLabel = "添加到收藏"\nfavoriteButton.accessibilityTraits = .button\n\n请注意 accessibilityTraits。这是给VoiceOver的提示,说明如何与元素交互。对于按钮使用 .button,对于图像使用 .image,对于标题使用 .header。使用 .selected、.notEnabled 等来准确传达状态。
元素分组:如何不让VoiceOver“唠叨”用户
\n\n有时将多个元素合并成一个有意义的块是合理的。例如,商品卡片:图片、名称、价格。如果VoiceOver逐个朗读,用户会感到疲惫。解决方案是使用 UIAccessibilityElement 或 shouldGroupAccessibilityChildren。
cardView.shouldGroupAccessibilityChildren = true\ncardView.accessibilityLabel = "Nike Air运动鞋,12,990卢布"\ncardView.accessibilityTraits = .button\n\n现在VoiceOver会将整个卡片作为一个元素朗读。简洁、精炼、易懂。
\n\n自定义操作:当需要比简单“点击”更多时
\n\n有些复杂元素:滑块、开关、滑动列表。为它们添加自定义操作很重要。例如,对于具有“删除”和“编辑”功能的单元格:
\n\nlet deleteAction = UIAccessibilityCustomAction(\n name: "删除",\n target: self,\n selector: #selector(deleteItem)\n)\nlet editAction = UIAccessibilityCustomAction(\n name: "编辑",\n target: self,\n selector: #selector(editItem)\n)\ncell.accessibilityCustomActions = [deleteAction, editAction]\n\nVoiceOver用户向下或向上滑动以选择操作。这大大改善了体验。
\n\nDynamic Type:适应每个人的文字
\n\n视力较弱的人经常在iOS设置中增大字体。如果您的应用不支持Dynamic Type,文字会被截断、重叠或变得无法阅读。如何避免这种情况?
\n\n使用动态字体样式
\n\n不要使用固定的 UIFont.systemFont(ofSize: 16),而应使用 UIFont.preferredFont(forTextStyle: .body)。
label.font = UIFont.preferredFont(forText