Реализация поддержки VoiceOver для iOS-приложения

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Реализация поддержки VoiceOver для iOS-приложения
Средний
~3-5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    871
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    755
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1178
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1051
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    978
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    574

VoiceOver — встроенный screen reader от Apple, позволяющий незрячим и слабовидящим пользователям взаимодействовать с устройством. Если ваше приложение его не поддерживает, они просто не могут им пользоваться. Мы проводим аудит и внедрение VoiceOver под ключ, гарантируя соответствие стандартам доступности. Наш опыт — более 5 лет в разработке iOS-приложений для различных отраслей. Свяжитесь с нами для оценки вашего приложения.

Почему VoiceOver важен для бизнеса?

По данным Apple, более 15% пользователей iOS активно используют функции доступности. Игнорирование этой аудитории приводит к потере до 15% потенциальных клиентов. Кроме того, многие контракты в государственном секторе, медицине и образовании требуют соответствия WCAG 2.1 или Section 508. Приложения без VoiceOver не проходят эти требования, что ограничивает рынок сбыта. Более того, несоответствие стандартам может повлечь юридические санкции и финансовые штрафы. Автоматизированный аудит сокращает время проверки в 3–5 раз по сравнению с ручным, а исправление ошибок на этапе разработки обходится на 40% дешевле, чем после релиза.

Какие элементы приложения ломаются без VoiceOver?

Кастомные UIView и SwiftUI View

Стандартные UIButton, UILabel, UITextField — VoiceOver понимает из коробки. Кастомные UIView с нарисованным на CALayer контентом — нет. VoiceOver видит весь кастомный view как один элемент без описания.

Для UIKit: isAccessibilityElement = true, accessibilityLabel, accessibilityHint, accessibilityTraits. accessibilityLabel — что это такое («Кнопка добавить в корзину»). accessibilityHint — что произойдёт при активации («Добавляет товар в корзину, переходит к оформлению»). accessibilityTraits — тип элемента (.button, .link, .image, .header, .selected).

Аспект UIKit SwiftUI
Label accessibilityLabel .accessibilityLabel()
Hint accessibilityHint .accessibilityHint()
Traits accessibilityTraits .accessibilityAddTraits()
Объединение детей Массив accessibilityElements .accessibilityElement(children: .combine)

Для SwiftUI: модификаторы .accessibilityLabel(), .accessibilityHint(), .accessibilityAddTraits(). Если несколько вложенных View нужно объединить в один accessible элемент — .accessibilityElement(children: .combine) или .accessibilityElement(children: .ignore) + явный label.

Изображения без alt-текста

UIImageView с isAccessibilityElement = false (по умолчанию) — VoiceOver пропускает. Декоративные изображения — правильно. Смысловые — нет, нужен accessibilityLabel. Иконки в кнопках: если UIButton содержит только UIImageView без текста — нужен accessibilityLabel на кнопке, иначе VoiceOver зачитает имя файла или молчит.

Порядок фокуса

VoiceOver обходит элементы по accessibilityActivationPoint — обычно центр frame. Для сложных layout (overlay, absolute positioning в SwiftUI, кастомные контейнеры) порядок может быть хаотичным. Исправляется через accessibilityElements на родительском контейнере — массив в нужном порядке:

override var accessibilityElements: [Any]? {
    get { [titleLabel, priceLabel, addButton] }
    set { }
}

В SwiftUI — .accessibilitySortPriority() для управления порядком.

Модальные экраны и кастомные оверлеи

UIAlertController — VoiceOver фокусируется автоматически. Кастомный UIView-оверлей поверх контента — нет. Нужно UIAccessibility.post(notification: .screenChanged, argument: firstElement) чтобы перевести фокус на первый элемент оверлея. При закрытии — post(notification: .screenChanged, argument: triggerButton) чтобы вернуть фокус на кнопку, которая открыла оверлей.

accessibilityViewIsModal = true на контейнере оверлея — скрывает фоновой контент от VoiceOver. Без этого пользователь свайпом может «провалиться» сквозь оверлей на задний контент.

Как мы проводим аудит и внедрение: пошаговый процесс

  1. Включение VoiceOver — Cmd+F5 в Simulator или тройной клик Home/Side Button на устройстве. Проходим все ключевые флоу: онбординг, главный экран, основные actions (оформить заказ, отправить сообщение, воспроизвести медиа).
  2. Фиксация проблем — элементы без label, неправильный порядок фокуса, недостижимые элементы, модальные оверлеи без управления фокусом.
  3. Инструменты — Accessibility Inspector (Xcode) проверяет контрасность, находит элементы без label без запуска приложения. XCTest с XCUIAccessibilityAudit (iOS 17+) даёт автоматизированный аудит в UI-тестах.
  4. Приоритет исправлений — сначала навигация и ключевые CTA, потом списки и формы, потом медиа-контент.

Сравнение ручного и автоматизированного тестирования:

Критерий Ручное тестирование Автоматизированный аудит
Время на один экран 10–15 мин 1–2 мин
Охват Выборочный Полный (все элементы)
Точность Зависит от тестировщика Стабильная
Повторяемость Низкая Высокая (можно в CI)

Что входит в работу?

  • Аудит доступности с отчётом по каждому экрану и приоритетом исправлений.
  • Реализация accessibility labels, hints, traits для всех кастомных компонентов.
  • Настройка порядка фокуса для сложных layout и модальных окон.
  • Интеграция с VoiceOver для динамического контента (например, обновление после загрузки).
  • Тестирование с помощью Accessibility Inspector и ручное прохождение ключевых сценариев.
  • Документация и рекомендации для команды по поддержке доступности в будущем.

Срок: 3-5 дней для приложения среднего масштаба. Стоимость рассчитывается индивидуально — напишите нам, и мы оценим ваш проект. Получите консультацию по вашему проекту — мы поможем внедрить VoiceOver качественно и в срок.

Типичные ошибки при реализации VoiceOver

  • Забывают задать accessibilityLabel для кнопок-иконок (только изображение).
  • Не используют accessibilityTraits, из-за чего VoiceOver не отличает кнопку от статического текста.
  • Не обрабатывают dynamic type — шрифты не масштабируются, и текст обрезается.
  • Игнорируют порядок фокуса на экранах с кастомной анимацией или overlay.

Избегая этих ошибок, вы делаете приложение доступным для миллионов пользователей.

Доступность мобильных приложений: VoiceOver, TalkBack и WCAG на практике

Приложение отклонили в App Store по гайдлайну 1.1, или пришёл запрос от корпоративного клиента с требованием WCAG 2.1 AA — обе ситуации означают одно: accessibility не был заложен в архитектуру с самого начала, а теперь его нужно встраивать в готовый продукт. Это больно.

Почему «добавить доступность потом» не работает

Самая частая проблема — разработчики воспринимают 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 + дополнения WCAG для мобильных стали де-факто стандартом при корпоративных тендерах и госзакупках.

Критичные критерии применительно к мобилу:

  • 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 недель в зависимости от числа экранов и глубины проблем. Внедрение accessibility с нуля в новый проект практически не влияет на сроки при правильном дизайне компонентной системы — закладываем 10-15% overhead на разработку UI-слоя.