Accessibility Label — 它是什么,基础知识以及如何为 iOS 和 Android 使用

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

Accessibility Label 是界面元素的名称,VoiceOver(iOS)或 TalkBack(Android)在聚焦时会念出它。在 iOS 中,该属性称为 accessibilityLabel,在 Android 中则称为 contentDescription,用于不包含文本的元素。根据 Apple Developer Documentation, 2024,标签是无障碍的基础:没有它,用户无法识别元素。标签在屏幕内必须是唯一的,并以易于理解的语言反映元素的本质。

要点

  • Accessibility Label — 屏幕读取器念出的元素名称;在 iOS 中通过 accessibilityLabel,在 Android 中通过 contentDescription 设置
  • Label 必须与元素的可见文本一致,或替代非文本组件的文本
  • 每个 Label 在屏幕内必须是唯一的——重复的标签会让用户困惑
  • Label 的本地化是必须的:标签要翻译成应用程序的所有支持的语言
  • 对于自定义控件,Label 通过覆写属性或 NSObject 协议编程设置

什么是 Accessibility Label

Accessibility Label是一个字符串属性,用于为辅助技术定义元素的名称。当用户开启 VoiceOver 并用手指在屏幕上滑动时,屏幕读取器会读出聚焦所在元素的 Label。没有标签,用户只能听到元素的类型:“按钮”、“图像”——而不知道其用途。

根据 Google I/O 2024「Accessibility Testing」,商店应用程序中 35% 的严重无障碍违反与 Label 缺失或不正确有关。Android 上的 Accessibility Scanner 将标签缺失检测为最严重级别的错误。

原则性限制:Label 不应包含元素类型。VoiceOver 和 TalkBack 会自动在声明中添加角色(按钮、标题、链接)。如果 Label 包含“发送按钮”,用户将听到:“发送按钮,按钮”——重复。

Label 和 WCAG 4.1.2:Name, Role, Value

WCAG 4.1.2(A 级)要求用户界面中的每个元素都具有可程序确定的名称(name)、角色(role)和值(value)。Accessibility Label 提供名称。如果 Label 缺失,则该条目被认为违反,应用程序无法通过基本认证。

iOS:accessibilityLabel 属性

在 iOS 中,accessibilityLabel被所有 UIView 从 UIAccessibility 协议继承。如果元素包含文本(带 title 的 UIButton、带 text 的 UILabel),Label 会自动设置为该文本。对于 UIImageView、自定义控件和容器,需要手动设置 Label。

自定义表格单元格的示例:

swift
class CustomTableViewCell: UITableViewCell {
    let titleLabel = UILabel()
    let priceLabel = UILabel()

    override func awakeFromNib() {
        super.awakeFromNib()
        self.isAccessibilityElement = true
        self.accessibilityLabel =
            "\(titleLabel.text ?? "") - \(priceLabel.text ?? "")"
    }
}

对于自定义 UIView,可以覆写 accessibilityLabel 的 getter:

swift
class RatingView: UIView {
    var rating: Int = 5

    override var accessibilityLabel: String? {
        get { return "评分:\(rating) / 5" }
        set {}
    }
}

Apple HIG, 2024 建议:如果元素由多个子元素组成(例如带有名称和价格的产品卡片),请将它们组合成一个具有复合 Label 的无障碍元素。在父元素上设置 isAccessibilityElement = true,在子元素上设置 false。

NSAttributedString 和 accessibilityLabel

如果 UILabel 使用 NSAttributedString,accessibilityLabel 默认等于 .string(纯文本)。如果需要传递语义上不同的值(例如,图标符号应读作“星星”而非符号 ★),请显式设置 accessibilityLabel。VoiceOver 无法有意义地读取 Unicode 符号。

Android:通过 contentDescription 的 Label

在 Android 中,contentDescription担任 ImageView、ImageButton 和自定义 View 的 Label。对于内置文本的 TextView 和 Button,无需设置 contentDescription——TalkBack 会自动读取文本。

通过 Kotlin 进行编程设置:

kotlin
binding.iconStar.contentDescription = "商品在收藏夹中"

// 对于具有多个元素的自定义视图
binding.customCard.setContentDescription(
    "\(title) 金额 \(price)")

在 XML 中用于装饰性元素:

xml
<ImageView
    android:contentDescription="@null"
    android:src="@drawable/divider"
    android:importantForAccessibility="no" />

importantForAccessibility = "no"属性完全将元素从无障碍树中排除。在 iOS 中,它的等效属性是 isAccessibilityElement = false。

Compose:semantics 和 contentDescription

在 Jetpack Compose 中,Label 通过semantics修饰符设置:

kotlin
Image(
    painter = painterResource(R.drawable.ic_search),
    contentDescription = "商品搜索",
    modifier = Modifier.semantics {
        contentDescription = "商品搜索"
    }
)

在 Compose 中,contentDescription 是 Image 的必须参数——没有它,代码将无法编译(警告)。这通过 API 设计强制提升了无障碍。

Label 和 Hint:作用的区别

Accessibility Label回答“这是什么元素?”的问题。Hint(iOS 中的 accessibilityHint,Android 中 contentDescription 中的附加文本)——“交互时会发生什么?”。VoiceOver 会顺序念出它们:先 Label,后 Hint。

删除按钮的示例:

  • Label:“删除”
  • Hint:“将不可撤销地删除所选照片”
  • VoiceOver:“删除。将不可撤销地删除所选照片”

根据 Deque University, 2024,Label 和 Hint 的正确分离使 VoiceOver 用户的任务完成率提高了 28%。有认知障碍的用户尤其依赖 Hint:如果没有说明就冒险按下“删除”,40%的用户会放弃操作。

何时不需要 Hint

  • 具有直觉可懂操作的元素(“返回”、“关闭”——Label 足够)
  • Label 已经描述了结果(“发送消息”——动词在名称本身)
  • 系统控件(UISwitch、带系统类型的 UIButton)——其行为是标准的

实践中的错误:用 Label 代替 Hint

常见错误:在 Label 中写“删除按钮”而非“删除”。元素类型(按钮)由 VoiceOver 通过 trait 自动添加。结果,用户听到:“删除按钮,按钮”——重复。正确的 Label:“删除”,Hint:“将删除所选照片”

本地化和最佳实践

标签的本地化是必须的——通过标准机制实现:iOS 中的 NSLocalizedString,Android 中的 @string/ 字符串资源。切勿在没有本地化的情况下用英语拼接方式设置 Label。

基于 W3C WCAG 2.2 的良好 Label 规则:

  • 以关键词开头——“产品搜索”,而非“产品搜索的字段”
  • 不要包含“按钮”、“字段”、“图像”等词——角色会自动添加
  • 使用目标受众能理解的自然语言
  • 避免缩写(除了常见的:“个”、“公斤”)——屏幕读取器会按字面读取
  • 对于输入元素,添加示例:“电子邮件(example@domain.com)”

品牌内 Label 的一致性

在应用程序中为 Label 使用统一的词汇表。如果一个屏幕上写着“收藏”,而另一个屏幕上写着“书签”,用户就会困惑。创建一个无障碍术语表——与设计师和本地化人员协调。

表单元素的 Label

对于输入字段(UITextField、EditText),Label 应与填充文本或字段标题一致。但是填充文本在输入文本后常常会消失。使用 accessibilityLabel 作为永久名称,使用 accessibilityValue 作为字段当前内容——这是 WCAG 4.1.2 标准。解决方案:静态设置 accessibilityLabel(等于字段标题),动态设置 accessibilityValue(等于输入的文本)。在 iOS 中这是自动的,但对于自定义字段——需要通过覆写 accessibilityValue 手动实现。检查 VoiceOver 是否读取“电子邮件,example@domain.com,文本字段”而非“,文本字段”。

如何测试无障碍标签

自动化测试是保证 Label 在所有屏幕上正确性的唯一方法。iOS 提供了 XCUIApplication,可以访问 .label,Android 则提供 AccessibilityCheckRule 和 setContentDescription。

iOS 测试示例:

swift
func testLabelsAreUnique() {
    let app = XCUIApplication()
    app.launch()
    let allButtons = app.buttons.allElementsBoundByIndex
    let labels = allButtons.compactMap { $0.label }
    let uniqueLabels = Set(labels)
    XCTAssertEqual(labels.count, uniqueLabels.count,
        "发现重复的 Label")
}

使用 Espresso 的 Android 测试示例:

kotlin
@Test
fun testButtonHasAccessibilityLabel() {
    onView(withId(R.id.btnSubmit))
        .check(matches(
            withContentDescription(containsString("发送"))
        ))
}

手动测试:开启 VoiceOver(iOS)或 TalkBack(Android),然后用手指向右滑动遍历屏幕上的所有元素。每个元素应收到有意义的声明。如果只听到“按钮”或“图像”——Label 缺失。

VoiceOver 转盘和快速导航

设置 Label 后,VoiceOver 用户可以使用转盘进行快速导航:“按钮”、“标题”、“链接”等模式。如果 Label 设置正确,VoiceOver 将元素包含在相应的转盘模式中。检查所有按钮是否在“按钮”模式中可见,所有标题是否在“标题”模式中可见。

Label 还影响 VoiceOver 的搜索功能。用户可以在搜索模式中输入词语,VoiceOver 将把聚焦移到具有匹配 Label 的元素上。因此,Label 应包含用户查找元素时使用的关键词。

集成到 CI/CD 管道

将 Label 检查添加到管道。在 iOS 上,使用带 fastlane scan 的XCUITest。在 Android 上,使用Accessibility Test Framework,其 AccessibilityCheckRule 规则可检测空的 contentDescription。这可以避免在合并新屏幕时产生回退。

常见问题

Accessibility Label 和 Accessibility Hint 有什么区别?

Label 标识元素(“搜索”),Hint 解释操作的结果(“将打开搜索屏幕”)。VoiceOver 在聚焦时立即念出 Label,而 Hint 在详细描述模式下念出。

带文本的 UILabel 是否需要设置 Label?

在 iOS 中,UILabel会自动获取与其文本相同的 accessibilityLabel。无需额外设置。在 Android 中,TextView 的行为类似。

如何为自定义 UIView 设置 Label?

在父 View 上设置isAccessibilityElement = true,并覆写 accessibilityLabel,返回从子元素拼接的文本。对于复杂组件,使用分隔符进行拼接。

如何避免屏幕上 Label 的重复?

为重复元素添加上下文:“购买 iPhone 15”、“购买 iPhone 15 Pro”。通过 UI 测试自动化检查——收集所有 Label 并检查无重复。

可以使用 Label 将元素隐藏不被屏幕读取器读取吗?

不可以。要隐藏元素,请在 iOS 中使用isAccessibilityElement = false,或在 Android 中使用 importantForAccessibility = "no"。空 Label 不会隐藏元素——屏幕读取器将读取“无名称”。

总结

  • Accessibility Label — VoiceOver 和 TalkBack 的元素名称;在 iOS 中通过 accessibilityLabel,在 Android 中通过 contentDescription 设置
  • Label 应与文本元素的可见文本一致;对非文本元素(图标、图像)手动设置
  • Hint 回答“会发生什么?”的问题,不重复 Label——这两个属性具有不同的作用
  • 每个 Label 在屏幕上必须是唯一的;重复会困惑屏幕读取器用户
  • 本地化通过 NSLocalizedString(iOS)和 @string(Android)必须实现
  • 测试 Label 通过自动化 UI 测试(XCUIApplication、AccessibilityCheckRule)和手动通过 VoiceOver
  • 通过isAccessibilityElement = false 或 importantForAccessibility = "no" 隐藏装饰性元素

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

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

讨论项目

另请阅读