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 — ім’я елемента, яке озвучує екранний читач; задається через accessibilityLabel у iOS та contentDescription у Android
  • Мітка повинна збігатися з видимим текстом елемента або замінювати його для нетекстових компонентів
  • Кожна мітка повинна бути унікальною в межах екрану — дублюючі мітки дезорієнтують користувача
  • Локалізація міток обов’язкова: мітки перекладаються на всі підтримувані мови додатка
  • Для користувацьких контролів мітка задається програмно через перевизначення властивості або протоколу NSObject

Що таке Accessibility Label

Accessibility Label — це рядкова властивість, яка визначає ім’я елемента для допоміжних технологій. Коли користувач проводить пальцем по екрану з увімкненим VoiceOver, екранний читач зчитує мітку елемента, на якому знаходиться фокус. Без мітки користувач чує лише тип елемента: «кнопка», «зображення» — без зазначення призначення.

Згідно з Google I/O 2024, «Accessibility Testing», 35% критичних порушень доступності в магазинних додатках пов’язані з відсутністю або некоректністю міток. Accessibility Scanner на Android виявляє відсутність мітки як помилку найвищої серйозності.

Основоположне обмеження: Мітка не повинна містити тип елемента. VoiceOver та TalkBack автоматично додають роль (кнопка, заголовок, посилання) до оголошення. Якщо мітка містить «Кнопка відправлення», користувач почує: «Кнопка відправлення, кнопка» — дублювання.

Label та WCAG 4.1.2: Ім’я, Роль, Значення

WCAG 4.1.2 (рівень A) вимагає, щоб кожен елемент користувацького інтерфейсу мав програмно визначувані ім’я, роль та значення. Accessibility Label надає ім’я. Якщо мітка відсутня, критерій вважається порушеним, і додаток не проходить базову сертифікацію.

iOS: властивість accessibilityLabel

У iOS accessibilityLabel успадковується всіма UIView від протоколу UIAccessibility. Якщо елемент містить текст (UIButton з назвою, UILabel з текстом), мітка автоматично встановлюється на цей текст. Для UIImageView, користувацьких контролів та контейнерів мітку потрібно задавати вручну.

Приклад для користувацької комірки таблиці:

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:

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

    override var accessibilityLabel: String? {
        get { return "Оцінка: \(rating) з 5" }
        set {}
    }
}

Apple HIG, 2024 радить: якщо елемент складається з кількох піделементів (наприклад, картка товару з назвою та ціною), об’єднайте їх в один елемент доступності з складеною міткою. Встановіть isAccessibilityElement = true на батьківському елементі та false на дочірних.

NSAttributedString та accessibilityLabel

Якщо UILabel використовує NSAttributedString, accessibilityLabel типово дорівнює .string (звичайний текст). Якщо потрібно передати семантично інше значення (наприклад, значок-символ читається як «Зірка» замість символу ★), явно встановіть accessibilityLabel. VoiceOver не читає символи Unicode осмислено.

Android: Label через contentDescription

У Android contentDescription виконує функцію Label для ImageView, ImageButton та користувацьких View. Для TextView та Button зі вбудованим текстом задавати contentDescription не потрібно — TalkBack читає текст автоматично.

Програмне задання через Kotlin:

kotlin
binding.iconStar.contentDescription = "Товар в обраному"

// Для користувацького View з багатьома елементами
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 (accessibilityHint у iOS, додатковий текст у contentDescription у Android) — «Що відбудеться при взаємодії?». VoiceOver вимовляє їх послідовно: спочатку Label, потім Hint.

Приклад для кнопки видалення:

  • Label: «Видалити»
  • Hint: «Безповоротно видаляє вибране фото»
  • VoiceOver: «Видалити. Безповоротно видаляє вибране фото»

Згідно з Deque University, 2024, правильне розділення Label та Hint підвищує рівень виконання завдань для користувачів VoiceOver на 28%. Користувачі з когнітивними порушеннями особливо залежні від Hint: не будучи впевненими щодо натискання «Видалити» без пояснення, 40% відмовляються від дії.

Коли Hint не потрібен

  • Елемент з інтуїтивно зрозумілою дією («Назад», «Закрити» — Label достатньо)
  • Label вже описує результат («Надіслати повідомлення» — діеслово в самій назві)
  • Системні контроли (UISwitch, UIButton з системним типом) — їхня поведінка стандартна

Помилки з практики: Label замість Hint

Часта помилка: у Label пишуть «Кнопка видалення» замість «Видалити». Тип елемента (Кнопка) додається VoiceOver автоматично через трейт. У результаті користувач чує: «Кнопка видалення, кнопка» — дублювання. Правильний Label: «Видалити», Hint: «Видаляє вибране фото».

Локалізація та кращі практики

Локалізація міток обов’язкова — вона здійснюється через стандартні механізми: NSLocalizedString у iOS, рядкові ресурси @string/ у Android. Ніколи не задавайте мітку конкатенацією англійською без локалізації.

Правила хорошої мітки, засновані на W3C WCAG 2.2:

  • Починайте з ключового слова — «Пошук товарів», а не «Поле для пошуку товарів»
  • Не включайте слова «кнопка», «поле», «зображення» — роль додається автоматично
  • Використовуйте природну мову, зрозумілу цільовій аудиторії
  • Уникайте скорочень (крім загальноприйнятих: «шт.», «кг») — екранний читач читає їх дослівно
  • Для елементів введення додавайте приклад: «Електронна пошта (приклад@домен.com)»

Консистентність міток в межах бренду

Використовуйте єдиний глосарій для міток у всьому додатку. Якщо на одному екрані написано «Улюблені», а на іншому «Закладки», користувач дезорієнтований. Створіть таблицю термінів доступності — узгодьте з дизайнерами та локалізаторами.

Label для елементів форм

Для полів введення (UITextField, EditText) Label повинен збігатися з placeholder або підписом поля. Однак placeholder часто зникає після введення тексту. Використовуйте accessibilityLabel для постійного імені та accessibilityValue для поточного вмісту поля — це стандарт WCAG 4.1.2. Рішення: встановіть accessibilityLabel статично (рівним підпису поля) та accessibilityValue динамічно (рівним введеному тексту). У iOS це автоматично, але для користувацьких полів — вручну через перевизначення accessibilityValue. Перевірте, що VoiceOver читає: «Електронна пошта, приклад@домен.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")
}

Приклад для Android з Espresso:

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 використовуйте XCUITest з fastlane scan. На Android використовуйте Accessibility Test Framework з правилом AccessibilityCheckRule, яке виявляє порожні contentDescription. Це запобігає регресіям при злитті нових екранів.

Часто задавані питання

Чим Accessibility Label відрізняється від Accessibility Hint?

Label ідентифікує елемент («Пошук»), Hint пояснює результат дії («Відкриє екран пошуку»). VoiceOver вимовляє Label одразу при фокусі, а Hint — у режимі детальних описів.

Чи потрібно задавати Label для UILabel з текстом?

У iOS UILabel автоматично отримує accessibilityLabel, рівний своєму тексту. Додатково задавати не потрібно. У Android TextView поводиться аналогічно.

Як задати Label для користувацького UIView?

Встановіть isAccessibilityElement = true на батьківському View та перевизначте accessibilityLabel, повернувши конкатенований текст з дочірних елементів. Для складних компонентів використовуйте об’єднання з роздільником.

Як уникнути дублювання Label на екрані?

Додавайте контекст до повторюваних елементів: «Купити iPhone 15», «Купити iPhone 15 Pro». Автоматизуйте перевірку через UI-тести — збирайте всі Label та перевіряйте відсутність дублікатів.

Чи можна використовувати Label для приховування елемента від екранного читача?

Ні. Для приховування елемента використовуйте isAccessibilityElement = false у iOS або importantForAccessibility = «no» у Android. Порожній Label не приховує елемент — екранний читач прочитає «без назви».

Підсумки

  • Accessibility Label — ім’я елемента для VoiceOver та TalkBack; задається через accessibilityLabel у iOS та contentDescription у Android
  • Label повинен збігатися з видимим текстом текстових елементів; для нетекстових (іконки, зображення) задається вручну
  • Hint відповідає на питання «Що відбудеться?» та не дублює Label — ці властивості мають різні ролі
  • Кожна мітка повинна бути унікальною на екрані; дублювання дезорієнтує користувача екранного читача
  • Локалізація міток обов’язкова через NSLocalizedString (iOS) та @string (Android)
  • Тестуйте Label автоматично через UI-тести (XCUIApplication, AccessibilityCheckRule) та вручну через VoiceOver
  • Декоративні елементи приховуйте через isAccessibilityElement = false або importantForAccessibility = «no»

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також