Accessibility — 基础,面向盲人用户的 VoiceOver 和 TalkBack

作者: IT Sectr 发布日期: 2026-02-26 阅读时间: 9 分钟

Accessibility(a11y)— 确保移动应用对残障人士的可访问性。包括屏幕朗读器支持(iOS 上的 VoiceOver、Android 上的 TalkBack)、文本缩放(Dynamic Type)、足够的色彩对比度(WCAG 2.1 AA 级别)、无需视觉的导航以及手势替代方案。根据世界卫生组织(2023年)的数据,超过13亿人(占人口的16%)患有某种形式的残疾——无障碍不是选项,而是必要。更多信息——参见 Apple 关于无障碍的官方文档

要点

  • Accessibility — 应用对残障人士的可访问性(视力、听力、运动能力)
  • VoiceOver — Apple 屏幕朗读器,在 iOS 和 macOS 上朗读界面元素
  • TalkBack — Google 面向 Android 的屏幕朗读器,支持无需视觉的手势控制
  • WCAG 2.1 — 国际无障碍标准:对比度 4.5:1,触摸区域大小 44×44pt
  • contentDescription — 用于描述 TalkBack 所朗读元素的 Android 属性

什么是移动应用中的 Accessibility (a11y)?

Accessibility(缩写为 a11y — 「a」和「y」之间的 11 个字母)—— 开发可供视力、听力、运动能力和认知特征障碍人士访问的应用的实践。在移动开发中,无障碍涵盖四种主要场景:盲人用户(屏幕朗读器)、弱视用户(缩放、对比度)、聋人和听障人士(字幕、声音的视觉替代方案)、运动能力受限用户(语音控制、Switch Control、大触摸区域)。

法律要求——在许多国家,无障碍是法律强制要求的。美国:《康复法案》第 508 条和《美国残疾人法案》。欧盟:《欧洲无障碍法案》(2025年)。英国:《平等法案 2010》。如果不支持无障碍,应用可能成为诉讼对象——2023年美国共提起了超过 4000 起关于数字产品不可访问的诉讼。Apple 和 Google 在审核应用时会检查无障碍:App Store 审核指南(4.2)和 Google Play Store 要求最低限度的无障碍支持。

商业论证——可访问性可以增加受众。根据 Return on Disability(2021年)的数据,残障人士每年控制着 13 万亿美元的可支配收入。可访问的应用在搜索中排名更靠前(语义化 HTML、替代文本),拥有更高的用户评分和更少的 UX 问题评论。在 IT Sectr,我们将无障碍纳入所有项目的「完成定义」——这是一个质量标准,而非可选改进。

iOS 中的无障碍:VoiceOver 和 UIAccessibility

VoiceOver——Apple 屏幕朗读器,内置于 iOS、iPadOS 和 macOS。用户在屏幕上滑动手指,VoiceOver 会朗读手指下方的元素名称。双击——激活元素。VoiceOver 支持超过 40 种手势:三指滑动(翻页)、两指双击(停止)、Z 形手势(返回)。开发者通过 UIAccessibility 协议以及 accessibilityLabel、accessibilityTraits、accessibilityHint 属性控制 VoiceOver 朗读的内容和方式。

swift
class CustomButton: UIButton {

    override var isAccessibilityElement: Bool {
        get { return true }
        set {}
    }

    // override accessibilityLabel
    override var accessibilityLabel: String? {
        get { return "发送表单按钮" }
        set {}
    }

    // override accessibilityHint
    override var accessibilityHint: String? {
        get { return "双击以发送数据" }
        set {}
    }

    // override accessibilityTraits
    override var accessibilityTraits: UIAccessibilityTraits {
        get { return .button }
        set {}
    }
}

// Dynamic Type — 文本缩放
titleLabel.font = UIFontMetrics.default.scaledFont(
    for: UIFont.systemFont(ofSize: 16)
)
titleLabel.adjustsFontForContentSizeCategory = true

动态排版——iOS 中的 Dynamic Type 允许用户选择文本大小(从 XS 到 XXXL)。开发者使用 UIFontMetrics.scaledFont 进行自动缩放。文本必须在所有大小下正确显示:行不能截断,按钮必须随文本比例增大。UITableView 在文本大小更改时自动更新单元格高度。忽略 Dynamic Type 意味着使应用对弱视用户不可访问。

SwiftUI 中的无障碍

SwiftUI 提供了无障碍修饰符:.accessibilityLabel()、.accessibilityHint()、.accessibilityAddTraits()、.accessibilitySortPriority()。默认情况下,所有标准 SwiftUI 元素(Text、Button、Image)都已经是具有自动标签的无障碍元素。对于自定义视图,使用 .accessibilityElement(children: .combine) 将子元素合并为一个。SwiftUI 自动支持 Dynamic Type 和 VoiceOver。

swift
VStack {
    Image(systemName: "trash")
        .accessibilityLabel(Text("删除元素"))
    Text("垃圾桶")
        .font(.body)
}
.accessibilityElement(children: .combine)
.accessibilityAddTraits(.isButton)
.accessibilityHint(Text("删除所选元素且无法恢复"))

Android 中的无障碍:TalkBack 和 contentDescription

TalkBack——Google 屏幕朗读器,预装在大多数 Android 设备上(在 Google Play 中可用于所有 Android 5+ 版本)。TalkBack 使用与 VoiceOver 相同的手势:滑动导航,双击激活。开发者通过 XML 中的 android:contentDescription 属性或代码中的 setContentDescription() 设置元素的描述。对于 ImageView,contentDescription 是必需的——没有它,TalkBack 会报告「未标记」或读取文件名。

kotlin
// XML:ImageView 的 contentDescription
<ImageView
    android:id="@+id/iconDelete"
    android:src="@drawable/ic_delete"
    android:contentDescription="@string/delete_button_desc"
    android:focusable="true"
    android:clickable="true" />

// Kotlin:编程设置
iconDelete.contentDescription = getString(R.string.delete_button_desc)

// Accessibility Delegate(自定义)
iconDelete.accessibilityDelegate = object : View.AccessibilityDelegate() {
    override fun onInitializeAccessibilityNodeInfo(
        host: View, info: AccessibilityNodeInfo
    ) {
        super.onInitializeAccessibilityNodeInfo(host, info)
        info.text = "删除按钮"
        info.contentDescription = "删除所选元素"
        info.className = Button::class.java.name
    }
}

// Live Regions 用于动态更新
textView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE

Live Regions——Android 通知 TalkBack 内容更改而无需焦点的机制。android:accessibilityLiveRegion 属性接受三个值:none(无通知)、polite(在当前之后宣布)、assertive(立即宣布)。对加载状态更新使用 polite,对严重错误使用 assertive。滥用 assertive 会给用户造成混乱——TalkBack 会不断中断当前操作。

Accessibility Scanner

Accessibility Scanner——来自 Google 的免费应用,用于测试 Android 应用的无障碍性,无需访问源代码。扫描器检查:文本对比度、触摸区域大小(根据 Android 无障碍指南最小为 48×48dp)、ImageView 是否有 contentDescription、元素层次结构的正确性。对于自动化测试,使用 Espresso 的 AccessibilityChecks(导入:androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.5.1')——它们集成到 CI/CD 中,并在每次构建时检查无障碍性。

WCAG 2.1:对比度、大小和触摸区域

WCAG 2.1(Web Content Accessibility Guidelines,网页内容无障碍指南)——由 W3C 制定的国际无障碍标准。2.1 版(2018年)包含 13 项针对移动应用的附加标准。符合级别:A(最低)、AA(对大多数组织是强制性的)、AAA(最高)。Apple 和 Google 推荐 AA 级别作为应用发布的最低标准。WCAG 2.2 于 2023 年发布,对焦点和输入进行了澄清。

移动开发的关键标准:文本对比度至少 4.5:1(AA)或 7:1(AAA),触摸区域大小最小 44×44pt(iOS)或 48×48dp(Android),支持横竖屏切换而功能不损失,可关闭动画(prefers-reduced-motion),多媒体存在字幕,兼容语音控制(iOS 上的 Voice Control,Android 上的 Voice Access)。

WCAG 2.1 标准级别iOS 要求Android 要求
1.4.3 对比度(文本)AA常规 4.5:1,大号 3:1常规 4.5:1,大号 3:1
1.4.11 对比度(非文本)AA图标、边框 3:1图标、边框 3:1
2.5.5 目标大小AAA44×44pt48×48dp
2.3.3 动画AAAprefers-reduced-motionandroid:animateLayoutChanges
4.1.2 名称、角色、值AaccessibilityLabel, traitscontentDescription, role

对比度检查工具——Colour Contrast Analyser (TPGI)、WebAIM Contrast Checker、Stark (Figma)、Accessibility Inspector (Xcode)。在 IT Sectr,我们在设计阶段(Figma + Stark)和开发阶段(Accessibility Inspector / Accessibility Scanner)再次检查对比度。最低要求——所有小于 18pt(14pt 粗体)的文本要求 4.5:1。对于标志和装饰性元素,不要求对比度。

无障碍测试:工具和检查清单

iOS 测试——Xcode 中的 Accessibility Inspector(Xcode → Open Developer Tool → Accessibility Inspector)检查每个元素的 label、traits、hint。VoiceOver 可以在设置中启用,或通过无障碍快捷方式(三次按下按钮)启用。对于自动化测试,使用带 XCTAssertTrue(app.staticTexts["label"].isAccessibilityElement) 的 XCUITest。Apple 建议在启用 VoiceOver 的情况下测试应用的所有屏幕。

Android 测试——Accessibility Scanner(Play Store)检查对比度、触摸区域大小、contentDescription。用于自动化:Espresso AccessibilityChecks(导入:androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.5.1')。Google 推荐检查清单:每个 ImageView 都有 contentDescription,触摸区域不小于 48×48dp,文本可缩放到 200% 而不截断,所有元素可通过 TalkBack 滑动访问。

IT Sectr 检查清单——在发布前我们检查:(1)VoiceOver/TalkBack 正确朗读所有元素,(2)文本可缩放到最大大小而不损失功能,(3)所有 ImageView 都有 contentDescription,(4)文本对比度在所有主题中≥4.5:1,(5)触摸区域≥44pt/48dp,(6)没有仅通过长按可访问的上下文菜单,(7)在系统设置中支持 Reduce Motion / Remove Animations。此检查清单是每个冲刺完成定义的一部分。

常见问题

VoiceOver 和 TalkBack 有什么区别?

VoiceOver——Apple 面向 iOS、iPadOS、macOS 的屏幕朗读器。使用单指和多指手势(滑动、双击)。TalkBack——Google 面向 Android 的对应产品,使用类似手势。VoiceOver 朗读 accessibilityLabel,TalkBack 朗读 contentDescription。两者都支持盲文显示器和语音控制。功能上没有根本区别。

Android 中的 contentDescription 是什么?

contentDescription——Android 中 View 的属性,设置 TalkBack 的文本描述。没有它,TalkBack 会报告「未标记」或读取类名(ImageView、Button)。通过在 XML 中使用 android:contentDescription="@string/desc" 或在代码中使用 view.contentDescription = "文本" 添加。对于装饰性图像,使用 contentDescription=@null。

无障碍的最小对比度是多少?

根据 WCAG 2.1 AA 级别:常规文本为 4.5:1,大号文本(18pt 或 14pt 粗体以上)为 3:1。AAA 级别:常规为 7:1,大号为 4.5:1。在两个主题(浅色/深色)中检查对比度。根据 Google 的数据,对比度违规是移动应用中最常见的无障碍问题。

iOS 中是否需要支持 Dynamic Type?

是的,Apple 建议所有应用都支持 Dynamic Type。用户在「设置」中设置文本大小。开发者使用 UIFontMetrics.scaledFont——字体自动缩放。没有 Dynamic Type,视力较弱的用户将无法阅读文本。iOS 在 App Store 审核时会自动检查 Dynamic Type。

什么是 WCAG?

WCAG(Web Content Accessibility Guidelines,网页内容无障碍指南)——来自 W3C 的国际内容无障碍标准。2.1 版(2018年)包括移动应用的标准:对比度、触摸区域大小(44×44pt)、屏幕朗读器支持、手势替代方案、字幕。AA 级别——在 App Store 和 Google Play 上发布的最低标准。

总结

  • Accessibility——为 13 亿残障人士提供的应用可访问性(WHO,2023)
  • VoiceOver(iOS)和 TalkBack(Android)——面向盲人用户的屏幕朗读器
  • UIAccessibility——iOS 协议,用于设置无障碍元素的 label、hint、traits
  • contentDescription——Android 属性,用于描述 TalkBack 的元素
  • WCAG 2.1——对比度 4.5:1,触摸区域 44×44pt,支持 Dynamic Type
  • Dynamic Type——通过 UIFontMetrics.scaledFont 在 iOS 中缩放文本
  • 测试——Accessibility Inspector(iOS)、Accessibility Scanner(Android)、Espresso Checks

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读