Focus Order — co to je, principy a jak to nastavit v mobilních aplikacích

Autor: IT Sectr Publikováno: 2026-05-16 Doba čtení: 9 min

Focus Order je pořadí, ve kterém prvky rozhraní získávají fokus při navigaci pomocí klávesnice, Switch Control, VoiceOveru nebo TalkBacku. V mobilních aplikacích pořadí fokusu určuje, jak se uživatel pohybuje mezi ovládacími prvky pomocí gest nebo tlačítek. Podle W3C WCAG 2.2, Success Criterion 2.4.3, 2023 musí fokus probíhat v logickém pořadí, které zachovává smysl obsahu. Porušení tohoto principu je jedním z častých důvodů neúspěchu auditu přístupnosti.

Hlavní body

  • Focus Order — pořadí procházení interaktivních prvků při navigaci klávesnicí nebo screen readerem
  • Fokus musí sledovat vizuální pořadí (zleva doprava, shora dolů) a zachovávat logiku obsahu
  • V iOS se pořadí řídí přes shouldGroupAccessibilityElement a pole accessibilityElements
  • V Androidu atributy nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight určují sousedy fokusu
  • Vlastní obrazovky (mapy, plátna, hry) vyžadují programové řízení fokusu přes UIAccessibilityPostNotification

Co je to Focus Order v přístupnosti

Focus Order je pořadí, ve kterém se uživatel pohybuje mezi interaktivními prvky pomocí alternativních vstupních metod: klávesnice (Tab), Switch Control (krok za krokem), VoiceOver (gesto doprava/doleva) nebo TalkBack. Na rozdíl od myši nebo dotykové obrazovky, kde uživatel vybírá prvek přímo, je fokusová navigace lineární — každý krok posune fokus na další prvek.

Podle Apple HIG, 2024 VoiceOver používá pořadí prvků ve stromu přístupnosti, který se staví na základě vizuálního umístění: levý horní roh → pravý dolní roh. Pokud obrazovka obsahuje složitý layout (sloupce, Grid, ZStack), strom nemusí odpovídat vizuálnímu pořadí.

Princip WCAG 2.4.3: „Pokud lze webovou stránku postupně procházet po sekcích a pořadí fokusu ovlivňuje smysl, musí fokus probíhat v pořadí, které zachovává smysl a ovladatelnost”. Výjimka: dynamický obsah, kde fokus může skákat pro upoutání pozornosti (upozornění, modální okna).

Proč je Focus Order kritický pro přístupnost

Uživatel Switch Control (lidé s motorickým postižením) se mezi prvky pohybuje automaticky — cyklus za cyklem. Pokud je pořadí porušeno, uživatel stráví 3krát více času dokončením formuláře. Podle Deque University, 2024 správný Focus Order zkracuje čas vyplňování formuláře o 60 % pro uživatele podpůrných technologií.

Focus Order a modální okna

Zvláštní pozornost si zaslouží modální okna. Po otevření modálního okna se fokus musí okamžitě přesunout na první interaktivní prvek uvnitř modálu (obvykle tlačítko „Zavřít” nebo „Potvrdit”). Po zavření — vrátit se na prvek, který modální okno vyvolal. To je požadavek WCAG 2.4.3 a zároveň častá chyba.

iOS: správa pořadí fokusu

V iOS VoiceOver automaticky staví pořadí na základě geometrie: prvky se řadí podle Y, poté podle X. Pro obrazovky se složitou strukturou může být toto pořadí nesprávné — vývojář musí zasáhnout.

Hlavní nástroje:

  • shouldGroupAccessibilityElement — slučuje podřízené prvky do jednoho logického bloku
  • accessibilityElements — pole, které určuje vlastní pořadí podřízených prvků
  • UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, element) — programové přesunutí fokusu

Příklad nastavení vlastního pořadí pro kartu produktu:

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

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

Pro programové přesunutí fokusu po akci:

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

shouldGroupAccessibilityElement v praxi

Vlastnost shouldGroupAccessibilityElement je užitečná pro karty v kolekcích. Pokud nastavíte true na rodičovské kartě, VoiceOver vnímá celou kartu jako jeden prvek. Uživatel může dvakrát klepnout pro aktivaci celé karty nebo nastavit rotor pro navigaci uvnitř. Doporučuje se pro UICollectionViewCell a UITableViewCell.

Android: atributy směru fokusu

V Androidu TalkBack také používá geometrické pořadí, ale přednost mají explicitní atributy nextFocus*. Tyto atributy se nastavují v XML nebo programově:

AtributFunkcePříklad
nextFocusDownPrvek při navigaci dolů@+id/field_email
nextFocusUpPrvek při navigaci nahoru@+id/field_name
nextFocusLeftPrvek vlevo@+id/btn_back
nextFocusRightPrvek vpravo@+id/btn_next

Příklad pro registrační formulář:

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

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

Pro RecyclerView je pořadí fokusu dynamické — určuje ho adapter. Pokud mají buňky složitou strukturu, nastavte descendantFocusability = "beforeDescendants" a určete pořadí v uzlu prvku seznamu. Pro Jetpack Compose se pořadí fokusu nastavuje přes Modifier.focusOrder() a FocusOrder. Priorita: previous (podřízený), next (následující), custom key.

TouchDelegate, oblast dotyku a oblast fokusu

Pokud je prvek příliš malý pro fokus (menší než 44pt), zvětšete oblast dotyku přes TouchDelegate v iOS nebo minWidth/minHeight v Androidu. Podle Google Material Design, 2024 je minimální dotyková oblast 48×48dp. VoiceOver a TalkBack fokusují na bounding box prvku. Prvky menší než 30pt nemusí být dostupné pro gestový fokus — uživatel se k nim fyzicky nedostane prstem.

Typická porušení WCAG 2.4.3

Skákající fokus — když po akci (například smazání prvku) fokus skočí na začátek seznamu nebo na systémové tlačítko „Zpět”. Uživatel VoiceOveru ztrácí kontext. Řešení: programově přesuňte fokus na prvek nejbližší smazanému.

Neviditelný fokus — prvek získá fokus, ale neexistuje vizuální indikátor (uživatelé klávesnice nevidí, kde jsou). V iOS kontrolujte UIAccessibility.isVoiceOverRunning pro vlastní indikátory. Podle Deque University, 2024 je neviditelný fokus druhou nejčastější příčinou neúspěchu auditu přístupnosti.

Modální okna — fokus zůstává na obsahu na pozadí po otevření modálního okna. V iOS modální view automaticky zachytí fokus, pokud je nastaveno modalPresentationStyle = .pageSheet. V Androidu použijte setFocusable(true) na kontejneru dialogu.

Focus trap (past fokusu)

Opačný problém: fokus uvízne uvnitř modálního okna a nemůže ven (kromě zavření). To je povoleno pouze pro modální okna — uživatel musí okno vědomě zavřít. Pro běžné obrazovky je focus trap kritická chyba. Řešení: ujistěte se, že poslední prvek modálního okna (tlačítko „Zavřít”) předává fokus zpět.

Vlastní obrazovky a programový fokus

Pro vlastní obrazovky (mapy, plátna, hry) není automatické geometrické pořadí použitelné. Vývojář musí postavit strom přístupnosti ručně. V iOS se k tomu přepisuje metoda UIAccessibilityContainer.

Příklad pro vlastní plátno:

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

    override var accessibilityElements: [Any]? {
        get {
            // Řadíme tvary podle Z-indexu, ne podle geometrie
            return shapes.sorted { $0.zIndex < $1.zIndex }
        }
        set {}
    }
}

V Androidu pro vlastní View přepište onInitializeAccessibilityNodeInfo:

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

Pro dynamické seznamy (chat, zpravodajství) po přidání prvku vyvolejte přesun fokusu na první nový prvek. V iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). V Androidu: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).

AccessibilityFrame a geometrie fokusu

iOS automaticky určuje oblast fokusu na základě frame prvku. Pokud má prvek transformaci (transform, rotation), VoiceOver může fokusovat na nesprávnou oblast. Explicitně nastavte accessibilityFrame v souřadnicích obrazovky: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). To zaručuje, že VoiceOver zvýrazní správnou oblast.

UIKit Dynamics a přístupnost

Pro animované obrazovky (UIKit Dynamics, Lottie, SpriteKit) je programový fokus obzvlášť důležitý. VoiceOver nedokáže postavit strom přístupnosti pro dynamicky se pohybující prvky. Nastavte isAccessibilityElement = false na kontejnerech animací a true pouze na interaktivních prvcích uvnitř.

Testování pořadí fokusu

Ruční testování: zapněte VoiceOver (iOS) nebo TalkBack (Android), projeďte gestem doprava celé pořadí. Fokus musí sledovat vizuální pořadí — zleva doprava, shora dolů. Každý interaktivní prvek musí získat fokus přesně jednou.

Automatizované testování je obtížné, ale možné:

swift
func testKeyboardFocusOrder() {
    let app = XCUIApplication()
    app.launch()
    app.textFields["Email"].tap()
    // Tab — pouze s hardwarovou klávesnicí
}

Pro Android použijte 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()))
}

Nejspolehlivější metoda — UI test scénáře: vyplňte formulář krok za krokem (Email → Heslo → Odeslat), kontrolujte, že každý krok skončí úspěšně. Pokud je pořadí fokusu porušeno, scénář spadne při pokusu o interakci s prvkem mimo fokus.

Xcode Accessibility Inspector pro ladění

Nástroj Accessibility Inspector v Xcode zobrazuje kompletní strom přístupnosti. Můžete procházet prvky v pořadí VoiceOveru a vidět přesnou cestu fokusu. Použijte záložku „Audit” pro automatické vyhledávání porušení Focus Order.

Často kladené otázky

Co je WCAG 2.4.3 a jaké požadavky platí pro fokus?

WCAG 2.4.3 (Focus Order) — kritérium úspěšnosti úrovně A. Vyžaduje, aby pořadí fokusu zachovávalo smysl obsahu při postupné navigaci. Porušení se považuje za kritické a blokuje certifikaci.

Jak nastavit pořadí fokusu pro prvky skryté za animací?

Skryté prvky musí mít v iOS isAccessibilityElement = false nebo visibility = gone/invisible v Androidu. Při zobrazení programově přesuňte fokus přes UIAccessibility.post(notification: .layoutChanged).

Čím se liší fokus v iOS a Androidu?

iOS řídí přes accessibilityElements a shouldGroupAccessibilityElement, Android — přes atributy nextFocus* a AccessibilityNodeInfo. Princip je stejný: geometrické pořadí ve výchozím stavu s možností přepsání.

Co dělat, když má RecyclerView nesprávné pořadí?

Nastavte descendantFocusability = "beforeDescendants" na kořenovém prvku a nakonfigurujte pořadí v adapteru přes onInitializeAccessibilityNodeInfo pro každou buňku.

Jak zkontrolovat fokus bez VoiceOveru?

Připojte hardwarovou klávesnici přes Bluetooth nebo USB. V iOS stiskněte Tab pro přesun fokusu. V Androidu zapněte TalkBack a použijte klávesy Tab a šipky.

Shrnutí

  • Focus Order — pořadí procházení prvků při navigaci klávesnicí nebo screen readerem; vychází z WCAG 2.4.3
  • Fokus musí sledovat vizuální pořadí (zleva doprava, shora dolů) — automaticky ve VoiceOveru a TalkBacku
  • V iOS se pořadí řídí přes accessibilityElements a shouldGroupAccessibilityElement
  • V Androidu se používají atributy nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight
  • Vlastní obrazovky (mapy, plátna) vyžadují programové řízení fokusu přes UIAccessibilityPostNotification
  • Porušení pořadí je kritická chyba WCAG 2.4.3; uživatelé ztrácejí kontext a nemohou dokončit scénář
  • Testujte fokus gesty VoiceOver/TalkBack, hardwarovou klávesnicí a automatizovanými scénáři

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také