Focus Order — co to jest, zasady i jak skonfigurować w aplikacjach mobilnych

Autor: IT Sectr Opublikowano: 2026-05-16 Czas czytania: 9 min

Focus Order to sekwencja, w której elementy interfejsu otrzymują fokus podczas nawigacji za pomocą klawiatury, Switch Control, VoiceOver lub TalkBack. W aplikacjach mobilnych kolejność fokusu określa, jak użytkownik porusza się między kontrolkami za pomocą gestów lub przycisków. Według W3C WCAG 2.2, Success Criterion 2.4.3, 2023, fokus powinien podążać w logicznej kolejności, zachowującej sens treści. Naruszenie tej zasady to jedna z częstych przyczyn nieprzechodzenia audytu dostępności.

Najważniejsze

  • Focus Order — kolejność przechodzenia między elementami interaktywnymi podczas nawigacji klawiaturą lub czytnikiem ekranu
  • Fokus powinien podążać za kolejnością wizualną (od lewej do prawej, od góry do dołu) i zachowywać logikę treści
  • W iOS kolejność reguluje się przez shouldGroupAccessibilityElement i tablicę accessibilityElements
  • W Androidzie atrybuty nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight określają sąsiadów fokusu
  • Niestandardowe ekrany (mapy, canvasy, gry) wymagają programowego zarządzania fokusem przez UIAccessibilityPostNotification

Czym jest Focus Order w dostępności

Focus Order to sekwencja, w której użytkownik porusza się między elementami interaktywnymi za pomocą alternatywnych metod wprowadzania: klawiatury (Tab), Switch Control (krok po kroku), VoiceOver (gest w prawo/lewo) lub TalkBack. W przeciwieństwie do myszy lub ekranu dotykowego, gdzie użytkownik wybiera element bezpośrednio, nawigacja fokusem jest liniowa — każdy krok przenosi fokus na następny element.

Według Apple HIG, 2024, VoiceOver używa kolejności elementów w drzewie dostępności, które buduje się na podstawie rozmieszczenia wizualnego: lewy górny róg → prawy dolny róg. Jeśli ekran zawiera złożony układ (kolumny, Grid, ZStack), drzewo może nie odpowiadać kolejności wizualnej.

Zasada WCAG 2.4.3: „Jeśli stronę można przechodzić sekwencyjnie po sekcjach i kolejność fokusu wpływa na znaczenie, to fokus powinien podążać w kolejności zachowującej znaczenie i sterowalność”. Wyjątek: treść dynamiczna, gdzie fokus może skakać w celu przyciągnięcia uwagi (ostrzeżenia, okna modalne).

Dlaczego Focus Order jest krytyczny dla dostępności

Użytkownik Switch Control (osoby z zaburzeniami motorycznymi) porusza się po elementach automatycznie — cykl za cyklem. Jeśli kolejność jest zaburzona, użytkownik traci 3 razy więcej czasu na wypełnienie formularza. Według Deque University, 2024, prawidłowy Focus Order skraca czas wypełniania formularza o 60% dla użytkowników technologii wspomagających.

Focus Order a okna modalne

Szczególną uwagę należy zwrócić na okna modalne. Po otwarciu okna modalnego fokus powinien natychmiast przenieść się na pierwszy element interaktywny wewnątrz modala (zwykle przycisk „Zamknij” lub „Potwierdź”). Po zamknięciu — powrócić na element, który wywołał okno modalne. To wymaganie WCAG 2.4.3 i jednocześnie częsty błąd.

iOS: zarządzanie kolejnością fokusu

W iOS VoiceOver automatycznie buduje kolejność na podstawie geometrii: elementy są sortowane według Y, następnie według X. W przypadku ekranów o złożonej strukturze ta kolejność może być nieprawidłowa — programista musi interweniować.

Podstawowe narzędzia:

  • shouldGroupAccessibilityElement — łączy elementy potomne w jeden logiczny blok
  • accessibilityElements — tablica określająca niestandardową kolejność elementów potomnych
  • UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, element) — programowe przeniesienie fokusu

Przykład ustawiania niestandardowej kolejności dla karty produktu:

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

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

Do programowego przeniesienia fokusu po akcji:

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

shouldGroupAccessibilityElement w praktyce

Właściwość shouldGroupAccessibilityElement jest przydatna w przypadku kart w kolekcjach. Jeśli ustawimy true na karcie nadrzędnej, VoiceOver postrzega całą kartę jako jeden element. Użytkownik może dwukrotnie dotknąć, aby aktywować całą kartę, lub skonfigurować rotor do nawigacji wewnątrz. Zalecane dla UICollectionViewCell i UITableViewCell.

Android: atrybuty kierunku fokusu

W Androidzie TalkBack również używa kolejności geometrycznej, ale priorytet mają jawne atrybuty nextFocus*. Atrybuty te określa się w XML lub programowo:

AtrybutPrzeznaczeniePrzykład
nextFocusDownElement przy nawigacji w dół@+id/field_email
nextFocusUpElement przy nawigacji w górę@+id/field_name
nextFocusLeftElement z lewej@+id/btn_back
nextFocusRightElement z prawej@+id/btn_next

Przykład dla formularza rejestracji:

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

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

Dla RecyclerView kolejność fokusu jest dynamiczna — określa ją adapter. Jeśli komórki mają złożoną strukturę, ustaw descendantFocusability = „beforeDescendants" i określ kolejność w węźle elementu listy. Dla Jetpack Compose kolejność fokusu określa się przez Modifier.focusOrder() i FocusOrder. Priorytet: previous (potomny), next (następny), custom key.

TouchDelegate, hit area i obszar fokusu

Jeśli element jest zbyt mały dla fokusu (mniejszy niż 44 pt), zwiększ hit area przez TouchDelegate w iOS lub minWidth/minHeight w Androidzie. Według Google Material Design, 2024, minimalny obszar dotyku to 48×48 dp. VoiceOver i TalkBack skupiają się na bounding box elementu. Elementy mniejsze niż 30 pt mogą być niedostępne dla fokusu gestami — użytkownik fizycznie nie może w nie trafić palcem.

Typowe naruszenia WCAG 2.4.3

Skaczący fokus — gdy po akcji (np. usunięciu elementu) fokus przenosi się na początek listy lub systemowy przycisk „Wstecz". Użytkownik VoiceOver traci kontekst. Rozwiązanie: programowo przenosić fokus na element najbliższy usuniętemu.

Niewidoczny fokus — element otrzymuje fokus, ale nie ma wskaźnika wizualnego (użytkownicy klawiatury nie widzą, gdzie się znajdują). W iOS sprawdzaj UIAccessibility.isVoiceOverRunning dla niestandardowych wskaźników. Według Deque University, 2024, niewidoczny fokus to druga najczęstsza przyczyna niepowodzenia audytu dostępności.

Okna modalne — fokus pozostaje na treści tła po otwarciu okna modalnego. W iOS modalny widok automatycznie przechwytuje fokus, jeśli ustawiono modalPresentationStyle = .pageSheet. W Androidzie użyj setFocusable(true) na kontenerze dialogu.

Pułapka fokusu (focus trap)

Odwrotny problem: fokus więźnie wewnątrz okna modalnego i nie może wyjść (poza zamknięciem). Jest to dopuszczalne tylko w przypadku okien modalnych — użytkownik musi świadomie zamknąć okno. W przypadku zwykłych ekranów pułapka fokusu to krytyczny błąd. Rozwiązanie: upewnij się, że ostatni element okna modalnego (przycisk „Zamknij") przekazuje fokus z powrotem.

Niestandardowe ekrany i programowy fokus

Dla niestandardowych ekranów (mapy, canvasy, gry) automatyczna kolejność geometryczna nie ma zastosowania. Programista musi ręcznie zbudować drzewo dostępności. W iOS w tym celu nadpisuje się metodę UIAccessibilityContainer.

Przykład dla niestandardowego canvasu:

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

    override var accessibilityElements: [Any]? {
        get {
            // Sortujemy kształty według indeksu Z, a nie geometrii
            return shapes.sorted { $0.zIndex < $1.zIndex }
        }
        set {}
    }
}

W Androidzie dla niestandardowego View nadpisz onInitializeAccessibilityNodeInfo:

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

Dla list dynamicznych (czat, kanał newsów) po dodaniu elementu wywołaj przeniesienie fokusu na pierwszy nowy element. W iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). W Androidzie: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).

AccessibilityFrame i geometria fokusu

iOS automatycznie określa obszar fokusu na podstawie ramki elementu. Jeśli element ma transformację (transform, rotation), VoiceOver może skupiać się na nieprawidłowym obszarze. Jawnie ustaw accessibilityFrame we współrzędnych ekranu: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Gwarantuje to, że VoiceOver podświetli prawidłowy obszar.

UIKit Dynamics a dostępność

Dla ekranów animowanych (UIKit Dynamics, Lottie, SpriteKit) programowy fokus jest szczególnie ważny. VoiceOver nie może zbudować drzewa dostępności dla dynamicznie poruszających się elementów. Ustaw isAccessibilityElement = false na kontenerach animacji i true tylko na elementach interaktywnych wewnątrz.

Testowanie kolejności fokusu

Testowanie ręczne: włącz VoiceOver (iOS) lub TalkBack (Android), przesuń gestem w prawo przez całą sekwencję. Fokus powinien podążać za kolejnością wizualną — od lewej do prawej, od góry do dołu. Każdy element interaktywny powinien otrzymać fokus dokładnie raz.

Testowanie zautomatyzowane jest trudne, ale możliwe:

swift
func testKeyboardFocusOrder() {
    let app = XCUIApplication()
    app.launch()
    app.textFields["Email"].tap()
    // Tab — tylko z klawiaturą sprzętową
}

Dla Android użyj 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()))
}

Najbardziej niezawodną metodą jest test scenariusza UI: wypełnij formularz krok po kroku (Email → Hasło → Wyślij), sprawdzając, czy każdy krok kończy się pomyślnie. Jeśli kolejność fokusu jest zaburzona, scenariusz zakończy się niepowodzeniem przy próbie interakcji z elementem poza fokusem.

Xcode Accessibility Inspector do debugowania

Narzędzie Accessibility Inspector w Xcode pokazuje pełne drzewo dostępności. Możesz przejść przez elementy w kolejności VoiceOver i zobaczyć dokładną ścieżkę fokusu. Użyj zakładki „Audit" do automatycznego wyszukiwania naruszeń Focus Order.

Często zadawane pytania

Czym jest WCAG 2.4.3 i jakie są wymagania dotyczące fokusu?

WCAG 2.4.3 (Focus Order) to kryterium sukcesu poziomu A. Wymaga, aby kolejność fokusu zachowywała znaczenie treści podczas nawigacji sekwencyjnej. Naruszenie jest uznawane za krytyczne i blokuje certyfikację.

Jak ustawić kolejność fokusu dla elementów ukrytych za animacją?

Ukryte elementy powinny mieć isAccessibilityElement = false w iOS lub visibility = gone/invisible w Androidzie. Po pojawieniu się — programowo przenieś fokus przez UIAccessibility.post(notification: .layoutChanged).

Czym różni się fokus w iOS od Androida?

iOS zarządza przez accessibilityElements i shouldGroupAccessibilityElement, Android — przez atrybuty nextFocus* i AccessibilityNodeInfo. Zasada jest taka sama: domyślna kolejność geometryczna z możliwością nadpisania.

Co zrobić, gdy RecyclerView ma nieprawidłową kolejność?

Ustaw descendantFocusability = „beforeDescendants" na elemencie głównym i skonfiguruj kolejność w adapterze przez onInitializeAccessibilityNodeInfo dla każdej komórki.

Jak sprawdzić fokus bez VoiceOver?

Podłącz klawiaturę sprzętową przez Bluetooth lub USB. W iOS naciśnij Tab, aby przenieść fokus. W Androidzie włącz TalkBack i użyj klawiszy Tab oraz strzałek.

Podsumowanie

  • Focus Order — sekwencja przechodzenia między elementami podczas nawigacji klawiaturą lub czytnikiem ekranu; oparta na WCAG 2.4.3
  • Fokus powinien podążać za kolejnością wizualną (od lewej do prawej, od góry do dołu) — automatycznie w VoiceOver i TalkBack
  • W iOS kolejność reguluje się przez accessibilityElements i shouldGroupAccessibilityElement
  • W Androidzie używa się atrybutów nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight
  • Niestandardowe ekrany (mapy, canvasy) wymagają programowego zarządzania fokusem przez UIAccessibilityPostNotification
  • Naruszenie kolejności to krytyczny błąd WCAG 2.4.3; użytkownicy tracą kontekst i nie mogą ukończyć scenariusza
  • Testuj fokus przez gesty VoiceOver/TalkBack, klawiaturę sprzętową i zautomatyzowane scenariusze

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również