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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

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

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