iOS гайд

Accessibility на iOS - шпаргалка

Практический справочник, как делать приложения для iPhone и iPad удобными с VoiceOver, крупным текстом, Switch Control и системными настройками доступности.

Все материалы

1. Зачем это нужно

  • Лучше UX для всех: крупный текст, понятный фокус, меньше укачивания от анимаций.
  • App Store и HIG Apple ожидают базовую доступность.
  • Многие правки - маленькие API-решения: labels, traits и Dynamic Type.

2. Базовые API (UIKit + SwiftUI)

ЗадачаUIKitSwiftUI
Доступное имяaccessibilityLabel.accessibilityLabel()
ПодсказкаaccessibilityHint.accessibilityHint()
Значение (slider, switch)accessibilityValue.accessibilityValue()
Роль / поведениеaccessibilityTraits.accessibilityAddTraits()
Скрыть декоративноеisAccessibilityElement = false.accessibilityHidden(true)
Сгруппировать детейcontainer + combine.accessibilityElement(children: .combine)
Свои действияUIAccessibilityCustomAction.accessibilityAction()

3. Labels для VoiceOver

  • Описывайте действие, а не картинку: "Удалить сообщение", а не "Красная корзина".
  • Держите label коротким; детали - в hint.
  • Не дублируйте уже видимый текст в label, если VoiceOver и так его читает.
  • Для кнопок только с иконкой label обязателен.
  • Обновляйте label/value при смене состояния (Играет / Пауза, Выбрано / Не выбрано).
// SwiftUI
Button(action: delete) {
  Image(systemName: "trash")
}
.accessibilityLabel("Удалить сообщение")
.accessibilityHint("Удаляет это сообщение из чата")

// UIKit
button.accessibilityLabel = "Удалить сообщение"
button.accessibilityHint = "Удаляет это сообщение из чата"
button.accessibilityTraits = .button

4. Traits и роли

TraitКогда использовать
.buttonНажимаемый контрол с действием
.linkПереход на другой экран / URL
.headerЗаголовок секции для ротора
.selectedТекущий таб, chip или выбранная ячейка
.adjustableSlider / stepper со свайпом вверх-вниз
.imageОсмысленная картинка (не декор)
.updatesFrequentlyЖивые значения (таймер, % загрузки)

Выбирайте одну понятную роль. Конфликтующие traits путают VoiceOver.

5. Dynamic Type

  • Используйте text styles (body, headline, footnote), а не только фиксированный размер.
  • В UIKit: label.adjustsFontForContentSizeCategory = true вместе со style-шрифтом.
  • В SwiftUI: .font(.body) / семантические стили; проверяйте самые крупные Accessibility sizes.
  • Вёрстка не должна обрезать и наезжать текст на XXXL.
  • Лучше перенос строки, чем обрезка важного текста.
// UIKit
label.font = .preferredFont(forTextStyle: .body)
label.adjustsFontForContentSizeCategory = true
label.numberOfLines = 0

// SwiftUI
Text("Настройки аккаунта")
  .font(.title2)
  .fixedSize(horizontal: false, vertical: true)

6. Анимация, контраст и системные настройки

НастройкаЧто делать
Reduce MotionУбрать сильный parallax/zoom, оставить fade или без анимации
Increase ContrastУсилить границы и контраст текста/фона
Bold TextНе опираться только на сверхтонкие шрифты
Differentiate Without ColorНе передавать ошибку/статус только цветом
Button ShapesТекстовые кнопки должны оставаться похожими на кнопки
// SwiftUI пример Reduce Motion
@Environment(\.accessibilityReduceMotion) var reduceMotion

withAnimation(reduceMotion ? nil : .easeInOut) {
  isExpanded.toggle()
}

7. Порядок фокуса и группировка

  • Порядок чтения должен совпадать с визуальным (слева направо, сверху вниз).
  • Заголовок + подзаголовок + meta карточки часто лучше объединять в один элемент.
  • Декоративные картинки и разделители скрывайте от VoiceOver.
  • После закрытия модалки / навигации возвращайте фокус в понятное место.
  • У кастомных контролов должна быть нормальная accessibility-рамка (около 44x44 pt).

8. Чеклист перед релизом

#Проверка
1У каждой icon-кнопки есть label
2Ошибки форм объявляются текстом, а не только красным цветом
3Dynamic Type на максимальных размерах не ломает UI
4VoiceOver проходит главные пользовательские сценарии
5Для Reduce Motion есть спокойная альтернатива
6Важные изображения описаны, декоративные скрыты
7Выбранные состояния доступны через traits/value
8Заголовки sheet/dialog объявляются как headers

9. Как тестировать на устройстве

  1. Настройки - Универсальный доступ - VoiceOver (или Accessibility Inspector на Mac).
  2. Жесты: свайп - следующий элемент, double-tap - активировать, two-finger scrub - назад.
  3. Настройки - Экран и размер текста - Крупный текст - проверьте максимум.
  4. Включите Reduce Motion и Increase Contrast и пройдите ключевые экраны.
  5. Для автоматизации: XCTest accessibility audits / предупреждения Accessibility Inspector.