Доступність мобільних додатків: VoiceOver, TalkBack та WCAG на практиці
Додаток відхилили в App Store за гайдлайном 1.1, або прийшов запит від корпоративного клієнта з вимогою WCAG 2.1 AA—обидві ситуації означають одне: доступність не був закладений в архітектуру з самого початку, а тепер його потрібно вбудовувати в готовий продукт. Це болить.
Навіщо «додати доступність потім» не працює
Найчастіша проблема—розробники сприймають VoiceOver та TalkBack як косметику. Розставили accessibilityLabel, запустили Screen Reader та дивуються, навіщо фокус стрибає з кнопки «Купити» на декоративну іконку в куті.
На iOS помилка живе в неправильній групуванні елементів. Якщо UIStackView містить іконку + текст + ціну, VoiceOver читатиме їх як три окремих елементи замість одного. Рішення—isAccessibilityElement = false на контейнері + accessibilityElements з правильним порядком, або shouldGroupAccessibilityChildren = true. Здається дрібницею, але саме це робить різницю між «формально працює» та «користувач-сліпий може купити товар за 30 секунд».
На Android ситуація дзеркальна: contentDescription ставлять повсюдно, включаючи ImageView, які несуть тільки декоративну функцію. TalkBack починає зачитувати «іконка стрілка» між кожним значимим елементом. Правильно—android:importantForAccessibility="no" для декору та явні contentDescription тільки там, де це має сенс.
Dynamic Type та масштабування шрифтів
iOS Dynamic Type ломає верстку передбачувано: фіксовані висоти рядків в UILabel, захардкодені frame в Auto Layout, numberOfLines = 1 без adjustsFontSizeToFitWidth. Коли користувач встановлює розмір шрифту XXL в налаштуваннях, текст обрізається або перекриває сусідні елементи.
Правильна реалізація використовує .font = UIFont.preferredFont(forTextStyle: .body) з adjustsFontForContentSizeCategory = true та numberOfLines = 0 повсюдно, де контент динамічний. У SwiftUI це працює з коробки через .dynamicTypeSize() modifier.
На стороні Flutter еквівалент—textScaleFactor через MediaQuery. Компоненти Material 3 підтримують масштабування нативно, але кастомні віджети вимагають явного враховування.
WCAG 2.1 у мобільному контексті
Мобільні додатки формально не зобов'язані дотримуватися WCAG (він писався для вебу), але WCAG 2.1 + доповнення для мобільних стали де-факто стандартом при корпоративних тендерах та госзакупках.
Критичні критерії застосовно до мобільного:
- 1.4.3 Contrast Minimum—коефіцієнт контрастності тексту до фону мінімум 4.5:1. Перевіряємо через Xcode Accessibility Inspector або Android Studio Layout Inspector
- 2.4.7 Focus Visible—при роботі з зовнішньою клавіатурою на iPad/Android планшеті фокус повинен бути видний. Часто забутий сценарій
- 2.5.8 Target Size (AA)—мінімум 24x24dp для інтерактивних елементів, рекомендується 44pt/48dp
-
4.1.3 Status Messages—сповіщення про помилки форм повинні озвучуватися через
UIAccessibility.post(notification: .announcement)абоAccessibilityNodeInfo.RoleDescriptionна Android
Як будуємо процес
Аудит починається з Accessibility Inspector в Xcode та TalkBack developer settings на Android—проходимо все екрани зі Screen Reader включеним та фіксуємо кожен випадок, коли потрібно більше 3 дій для виконання цільової операції.
Далі—автоматизовані перевірки. XCUITest підтримує accessibility assertions; для Android використовуємо Accessibility Test Framework (ATF), який вбудований в Espresso. Це ловить регресії на CI.
Останній етап—тестування з реальними користувачами, які використовують вспомагальні технології. Ніяка автоматизація не замінює це.
| Інструмент | Платформа | Що перевіряє |
|---|---|---|
| Xcode Accessibility Inspector | iOS/macOS | Мітки, контраст, порядок фокуса |
| Android Accessibility Scanner | Android | Контраст, розміри touch targets |
| Deque axe DevTools | Cross-platform | WCAG-відповідність |
| VoiceOver (iOS) | iOS | Навігація через Screen Reader |
| TalkBack (Android) | Android | Навігація через Screen Reader |
Графік
Аудит та базове виправлення існуючого додатку—від 2 до 5 тижнів залежно від числа екранів та глибини проблем. Впровадження доступності з нуля в новий проект практично не впливає на графіки при правильному дизайні компонентної системи—закладаємо 10-15% overhead на розробку UI-шару.







