Focus Order — что это, принципы и как настроить в мобильных приложениях

Автор: IT Sectr Опубликовано: 2026-05-16 Время чтения: 9 мин

Focus Order — это последовательность, в которой элементы интерфейса получают фокус при навигации с помощью клавиатуры, Switch Control, VoiceOver или TalkBack. В мобильных приложениях порядок фокуса определяет, как пользователь перемещается между контролами жестами или кнопками. По данным W3C WCAG 2.2, Success Criterion 2.4.3, 2023, фокус должен следовать в логическом порядке, сохраняющем смысл контента. Нарушение этого принципа — одна из частых причин непроходимости accessibility-аудита.

Главное

  • Focus Order — порядок обхода интерактивных элементов при навигации с клавиатуры или screen reader
  • Фокус должен следовать визуальному порядку (слева направо, сверху вниз) и сохранять логику контента
  • В iOS порядок регулируется через shouldGroupAccessibilityElement и массив accessibilityElements
  • В Android атрибуты nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight задают соседей фокуса
  • Кастомные экраны (карты, канвасы, игры) требуют программного управления фокусом через UIAccessibilityPostNotification

Что такое Focus Order в accessibility

Focus Order — это последовательность, в которой пользователь перемещается между интерактивными элементами с помощью альтернативных методов ввода: клавиатуры (Tab), Switch Control (шаг за шагом), VoiceOver (жест вправо/влево) или TalkBack. В отличие от мыши или сенсорного экрана, где пользователь выбирает элемент напрямую, фокусная навигация линейна — каждый шаг перемещает фокус на следующий элемент.

По данным Apple HIG, 2024, VoiceOver использует порядок элементов в дереве accessibility, которое строится на основе визуального расположения: левый верхний угол → правый нижний. Если экран содержит сложную вёрстку (колонки, Grid, ZStack), дерево может не соответствовать визуальному порядку.

Принцип WCAG 2.4.3: «Если веб-страницу можно последовательно перемещать по секциям и порядок фокуса влияет на смысл, то фокус должен следовать в порядке, сохраняющем смысл и возможность управления». Исключение: динамический контент, где фокус может прыгать для привлечения внимания (предупреждения, модальные окна).

Почему Focus Order критичен для accessibility

Пользователь Switch Control (люди с моторными нарушениями) перемещается по элементам автоматически — цикл за циклом. Если порядок нарушен, пользователь тратит в 3 раза больше времени на завершение формы. По данным Deque University, 2024, корректный Focus Order сокращает время заполнения формы на 60% для пользователей вспомогательных технологий.

Focus Order и модальные окна

Особое внимание — модальным окнам. После открытия модального окна фокус должен немедленно переместиться на первый интерактивный элемент внутри модалки (обычно кнопка «Закрыть» или «Подтвердить»). После закрытия — вернуться на элемент, который вызвал модальное окно. Это требование WCAG 2.4.3 и одновременно распространённая ошибка.

iOS: управление порядком фокуса

В iOS VoiceOver автоматически строит порядок на основе геометрии: элементы сортируются по Y, затем по X. Для экранов со сложной структурой этот порядок может быть некорректным — разработчик должен вмешаться.

Основные инструменты:

  • shouldGroupAccessibilityElement — объединяет дочерние элементы в один логический блок
  • accessibilityElements — массив, задающий кастомный порядок дочерних элементов
  • UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, element) — программное перемещение фокуса

Пример задания кастомного порядка для карточки товара:

swift
class ProductCardView: UIView {
    let titleLabel = UILabel()
    let priceLabel = UILabel()
    let buyButton = UIButton()

    override var accessibilityElements: [Any]? {
        get {
            return [titleLabel!, priceLabel!, buyButton!]
        }
        set {}
    }
}

Для программного перемещения фокуса после действия:

swift
UIAccessibility.post(
    notification: .layoutChanged,
    argument: newlyAddedItem
)

shouldGroupAccessibilityElement на практике

Свойство shouldGroupAccessibilityElement полезно для карточек в коллекциях. Если установить true на родительской карточке, VoiceOver воспринимает всю карточку как один элемент. Пользователь может дважды коснуться, чтобы активировать карточку целиком, или настроить ротор для навигации внутри. Рекомендуется для UICollectionViewCell и UITableViewCell.

Android: атрибуты направления фокуса

В Android TalkBack также использует геометрический порядок, но приоритет отдаётся явным атрибутам nextFocus*. Эти атрибуты задаются в XML или программно:

АтрибутНазначениеПример
nextFocusDownЭлемент при навигации вниз@+id/field_email
nextFocusUpЭлемент при навигации вверх@+id/field_name
nextFocusLeftЭлемент слева@+id/btn_back
nextFocusRightЭлемент справа@+id/btn_next

Пример для формы регистрации:

xml
<EditText
    android:id="@+id/field_email"
    android:nextFocusDown="@+id/field_password" />

<EditText
    android:id="@+id/field_password"
    android:nextFocusDown="@+id/btn_submit" />

Для RecyclerView порядок фокуса динамический — определяется адаптером. Если ячейки имеют сложную структуру, установите descendantFocusability = "beforeDescendants" и задайте порядок в узле элемента списка. Для Jetpack Compose порядок фокуса задаётся через Modifier.focusOrder() и FocusOrder. Приоритет: previous (дочерний), next (следующий), custom key.

TouchDelegate, hit area и область фокуса

Если элемент слишком мал для фокуса (меньше 44pt), увеличьте hit area через TouchDelegate в iOS или minWidth/minHeight в Android. По данным Google Material Design, 2024, минимальная область касания — 48×48dp. VoiceOver и TalkBack фокусируются на bounding box элемента. Элементы размером менее 30pt могут быть недоступны для жестового фокуса — пользователь физически не может попасть по ним пальцем.

Типовые нарушения WCAG 2.4.3

Прыгающий фокус — когда после акции (например, удаления элемента) фокус перемещается в начало списка или на системную кнопку «Назад». Пользователь VoiceOver теряет контекст. Решение: программно перемещать фокус на элемент, ближайший к удалённому.

Невидимый фокус — элемент получает фокус, но визуального индикатора нет (пользователи клавиатуры не видят, где находятся). В iOS проверяйте UIAccessibility.isVoiceOverRunning для кастомных индикаторов. По данным Deque University, 2024, невидимый фокус — вторая по частоте причина провала accessibility-аудита.

Модальные окна — фокус остаётся на фоновом контенте после открытия модального окна. В iOS модальный view автоматически захватывает фокус, если установлен modalPresentationStyle = .pageSheet. В Android используйте setFocusable(true) на контейнере диалога.

Focus trap (ловушка фокуса)

Обратная проблема: фокус застревает внутри модального окна и не может выйти (кроме закрытия). Это допустимо только для модальных окон — пользователь должен сознательно закрыть окно. Для обычных экранов focus trap — критическая ошибка. Решение: убедитесь, что последний элемент модального окна (кнопка «Закрыть») передаёт фокус обратно.

Кастомные экраны и программный фокус

Для кастомных экранов (карты, канвасы, игры) автоматический геометрический порядок неприменим. Разработчик должен построить дерево accessibility вручную. В iOS для этого переопределяется метод UIAccessibilityContainer.

Пример для кастомного канваса:

swift
class CanvasView: UIView {
    var shapes: [ShapeView] = []

    override var accessibilityElements: [Any]? {
        get {
            // Сортируем фигуры по Z-индексу, а не по геометрии
            return shapes.sorted { $0.zIndex < $1.zIndex }
        }
        set {}
    }
}

В Android для кастомной View переопределите onInitializeAccessibilityNodeInfo:

kotlin
override fun onInitializeAccessibilityNodeInfo(
    info: AccessibilityNodeInfo
) {
    super.onInitializeAccessibilityNodeInfo(info)
    info.addChild(firstElement)
    info.addChild(secondElement)
    info.isFocusable = true
}

Для динамических списков (чат, лента новостей) после добавления элемента вызывайте перемещение фокуса на первый новый элемент. В iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). В Android: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).

AccessibilityFrame и геометрия фокуса

iOS автоматически определяет область фокуса на основе frame элемента. Если элемент имеет трансформацию (transform, rotation), VoiceOver может фокусироваться на неправильной области. Явно задайте accessibilityFrame в координатах экрана: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Это гарантирует, что VoiceOver подсветит правильную область.

UIKit Dynamics и accessibility

Для анимированных экранов (UIKit Dynamics, Lottie, SpriteKit) программный фокус особенно важен. VoiceOver не может построить дерево accessibility для динамически движущихся элементов. Устанавливайте isAccessibilityElement = false на контейнерах анимации и true только на интерактивных элементах внутри.

Тестирование порядка фокуса

Ручное тестирование: включите VoiceOver (iOS) или TalkBack (Android), проведите жестом вправо по всей последовательности. Фокус должен следовать визуальному порядку — слева направо, сверху вниз. Каждый интерактивный элемент должен получить фокус ровно один раз.

Автоматизированное тестирование затруднено, но возможно:

swift
func testKeyboardFocusOrder() {
    let app = XCUIApplication()
    app.launch()
    app.textFields["Email"].tap()
    // Tab — только с аппаратной клавиатурой
}

Для Android используйте Accessibility Testing Framework:

kotlin
@Test
fun testFocusOrder() {
    onView(withId(R.id.fieldEmail))
        .check(matches(isFocusable()))
    onView(withId(R.id.fieldEmail))
        .perform(focus())
    onView(withId(R.id.fieldPassword))
        .check(matches(isFocused()))
}

Наиболее надёжный метод — UI-тест сценария: заполните форму пошагово (Email → Пароль → Отправить), проверяя, что каждый шаг завершается успешно. Если порядок фокуса нарушен, сценарий упадёт на попытке взаимодействия с элементом вне фокуса.

Xcode Accessibility Inspector для дебага

Инструмент Accessibility Inspector в Xcode показывает полное дерево accessibility. Вы можете пройти по элементам в порядке VoiceOver и увидеть точный фокусный путь. Используйте вкладку «Audit» для автоматического поиска нарушений Focus Order.

Часто задаваемые вопросы

Что такое WCAG 2.4.3 и какие требования к фокусу?

WCAG 2.4.3 (Focus Order) — критерий успеха уровня A. Требует, чтобы порядок фокуса сохранял смысл контента при последовательной навигации. Нарушение считается критическим и блокирует сертификацию.

Как задать порядок фокуса для элементов, скрытых за анимацией?

Скрытые элементы должны иметь isAccessibilityElement = false в iOS или visibility = gone/invisible в Android. При появлении — программно переместите фокус через UIAccessibility.post(notification: .layoutChanged).

Чем отличается фокус в iOS от Android?

iOS управляет через accessibilityElements и shouldGroupAccessibilityElement, Android — через атрибуты nextFocus* и AccessibilityNodeInfo. Принцип одинаков: геометрический порядок по умолчанию с возможностью переопределения.

Что делать, если RecyclerView имеет неправильный порядок?

Установите descendantFocusability = "beforeDescendants" на корневом элементе и настройте порядок в адаптере через onInitializeAccessibilityNodeInfo для каждой ячейки.

Как проверить фокус без VoiceOver?

Подключите аппаратную клавиатуру через Bluetooth или USB. В iOS нажмите Tab для перемещения фокуса. В Android включите TalkBack и используйте клавиши Tab и стрелки.

Итоги

  • Focus Order — последовательность обхода элементов при навигации с клавиатуры или screen reader; основана на WCAG 2.4.3
  • Фокус должен следовать визуальному порядку (слева направо, сверху вниз) — автоматически в VoiceOver и TalkBack
  • В iOS порядок регулируется через accessibilityElements и shouldGroupAccessibilityElement
  • В Android используются атрибуты nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight
  • Кастомные экраны (карты, канвасы) требуют программного управления фокусом через UIAccessibilityPostNotification
  • Нарушение порядка — критическая ошибка WCAG 2.4.3; пользователи теряют контекст и не могут завершить сценарий
  • Тестируйте фокус через VoiceOver/TalkBack жестами, аппаратную клавиатуру и автоматизированные сценарии

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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