Focus Order — шта је, принципи и како подесити у мобилним апликацијама

Аутор: IT Sectr Објављено: 2026-05-16 Време читања: 9 мин

Focus Order је секвенција у којој елементи интерфејса добијају фокус при навигацији помоћу тастатуре, Switch Control, VoiceOver или TalkBack. У мобилним апликацијама редослед фокуса одређује како корисник путује између контрола помоћу покрета или дугмада. Према W3C WCAG 2.2, Success Criterion 2.4.3, 2023, фокус мора да прати логички редослед који чува смисао садржаја. Кршење овог принципа је један од честих разлога непроласности аудита приступачности.

Главно

  • Focus Order — редослед обиласка интерактивних елемената при навигацији тастатуром или читачем екрана
  • Фокус мора да прати визуелни редослед (с лева надесно, одозгор надоле) и чува логику садржаја
  • У iOS-у редослед се регулише кроз shouldGroupAccessibilityElement и низ accessibilityElements
  • У Android-у атрибути nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight одређују суседе фокуса
  • Прилагођени екрани (мапе, платна, игрице) захтевају програмско управљање фокусом путем UIAccessibilityPostNotification

Шта је Focus Order у приступачности

Focus Order је секвенција у којој корисник путује између интерактивних елемената помоћу алтернативних метода уноса: тастатуре (Tab), Switch Control (корак по корак), VoiceOver (покрет удесно/улево) или TalkBack. За разлику од миша или екрана осетљивог, где корисник бира елеменат директно, фокусна навигација је линеарна — сваки корак помера фокус на следећи елеменат.

Према Apple HIG, 2024, VoiceOver користи редослед елемената у дрвету приступачности, које се гради на основу визуелног распореда: горњи леви угао → доњи десни угао. Ако екран садржи сложен распоред (колоне, Grid, ZStack), дрво може да не одговара визуелном редоследу.

Принцип WCAG 2.4.3: «Ако се веб страница може узастопно померати кроз секције и редослед фокуса утиче на смисао, онда би фокус требало да прати редослед који чува смисао и могућност управљања». Изузетак: динамички садржај где фокус може да скаче како би привукао пажњу (упозорења, модални прозори).

Зашто је Focus Order критичан за приступачност

Корисник 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×48 dp. VoiceOver и TalkBack се фокусирају на bounding box елемента. Елементи мањи од 30pt могу бити недоступни за гестовни фокус — корисник физички не може да их додирне прстом.

Типичне повреде WCAG 2.4.3

Скакући фокус — када након акције (нпр. брисања елемента) фокус прелази на почетак листе или на системско дугме «Назад». Корисник VoiceOver-а губи контекст. Решење: програмски померити фокус на елеменат најближи обрисаном.

Невидљиви фокус — елеменат добија фокус, али нема визуелног индикатора (корисници тастатуре не виде где су). У iOS-у проверавајте UIAccessibility.isVoiceOverRunning за прилагођене индикаторе. Према Deque University, 2024, невидљиви фокус је други по учесталости разлог неуспеха аудита приступачности.

Модални прозори — фокус остаје на позадинском садржају након отварања модалног прозора. У iOS-у модални поглед аутоматски захвата фокус ако је постављен modalPresentationStyle = .pageSheet. У Android-у користите setFocusable(true) на контејнеру дијалога.

Focus trap (замка фокуса)

Обрнути проблем: фокус застаје унутар модалног прозора и не може изаћи (осим затварања). Ово је дозвољено само за модалне прозоре — корисник мора свесно да затвори прозор. За обичне екране, замка фокуса је критична грешка. Решење: уверите се да последњи елеменат модалног прозора (дугме «Затвори») преноси фокус назад.

Прилагођени екрани и програмски фокус

За прилагођене екране (мапе, платна, игрице) аутоматски геометријски редослед није примењив. Програмер мора да изгради дрво приступачности ручно. У 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 и приступачност

За анимиране екране (UIKit Dynamics, Lottie, SpriteKit) програмски фокус је посебно важан. VoiceOver не може да изгради дрво приступачности за динамички покретне елементе. Поставите 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-у приказује пуно дрво приступачности. Можете проћи кроз елементе у 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 — редослед обиласка елемената при навигацији тастатуром или читачем екрана; заснован на 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. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође