Focus Order — ce este, principii și cum se configurează în aplicațiile mobile

Autor: IT Sectr Publicat: 2026-05-16 Timp de citire: 9 min

Focus Order este secvența în care elementele interfeței primesc focalizarea în timpul navigării cu ajutorul tastaturii, Switch Control, VoiceOver sau TalkBack. În aplicațiile mobile, ordinea focalizării determină modul în care utilizatorul se deplasează între comenzi cu gesturi sau butoane. Conform W3C WCAG 2.2, Success Criterion 2.4.3, 2023, focalizarea trebuie să urmeze o ordine logică care păstrează sensul conținutului. Încălcarea acestui principiu este una dintre cauzele frecvente ale nepromovării auditului de accesibilitate.

Puncte cheie

  • Focus Order — ordinea de parcurgere a elementelor interactive la navigarea cu tastatura sau cititor de ecran
  • Focalizarea trebuie să urmeze ordinea vizuală (de la stânga la dreapta, de sus în jos) și să păstreze logica conținutului
  • În iOS, ordinea se reglează prin shouldGroupAccessibilityElement și tabloul accessibilityElements
  • În Android, atributele nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight definesc vecinii focalizării
  • Ecranele personalizate (hărți, pânze, jocuri) necesită gestionare programatică a focalizării prin UIAccessibilityPostNotification

Ce este Focus Order în accesibilitate

Focus Order este secvența în care utilizatorul se deplasează între elementele interactive folosind metode alternative de intrare: tastatură (Tab), Switch Control (pas cu pas), VoiceOver (gest la dreapta/stânga) sau TalkBack. Spre deosebire de mouse sau ecran tactil, unde utilizatorul selectează direct un element, navigarea prin focalizare este liniară — fiecare pas mută focalizarea pe următorul element.

Conform Apple HIG, 2024, VoiceOver folosește ordinea elementelor în arborele de accesibilitate, care se construiește pe baza aranjamentului vizual: colțul stânga sus → colțul dreapta jos. Dacă ecranul conține un aspect complex (coloane, Grid, ZStack), arborele poate să nu corespundă ordinii vizuale.

Principiul WCAG 2.4.3: „Dacă o pagină web poate fi parcursă secvențial pe secțiuni și ordinea focalizării afectează sensul, atunci focalizarea trebuie să urmeze o ordine care păstrează sensul și operabilitatea”. Excepție: conținut dinamic, unde focalizarea poate sări pentru a atrage atenția (avertismente, ferestre modale).

De ce Focus Order este critic pentru accesibilitate

Utilizatorul Switch Control (persoane cu deficiențe motorii) se deplasează automat prin elemente — ciclu după ciclu. Dacă ordinea este încălcată, utilizatorul pierde de 3 ori mai mult timp pentru a finaliza un formular. Conform Deque University, 2024, un Focus Order corect reduce timpul de completare a formularului cu 60% pentru utilizatorii de tehnologii asistive.

Focus Order și ferestrele modale

O atenție specială — ferestrelor modale. După deschiderea unei ferestre modale, focalizarea trebuie să se mute imediat pe primul element interactiv din interiorul modalei (de obicei butonul „Închide” sau „Confirmă”). După închidere — să revină la elementul care a deschis fereastra modală. Aceasta este o cerință WCAG 2.4.3 și, în același timp, o eroare frecventă.

iOS: gestionarea ordinii de focalizare

În iOS, VoiceOver construiește automat ordinea pe baza geometriei: elementele se sortează după Y, apoi după X. Pentru ecranele cu structură complexă, această ordine poate fi incorectă — dezvoltatorul trebuie să intervină.

Instrumente principale:

  • shouldGroupAccessibilityElement — combină elementele copil într-un singur bloc logic
  • accessibilityElements — tabloul care definește ordinea personalizată a elementelor copil
  • UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, element) — mutarea programatică a focalizării

Exemplu de setare a ordinii personalizate pentru o carte de produs:

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

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

Pentru mutarea programatică a focalizării după o acțiune:

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

shouldGroupAccessibilityElement în practică

Proprietatea shouldGroupAccessibilityElement este utilă pentru cărțile din colecții. Dacă se setează true pe cartea părinte, VoiceOver percepe întreaga carte ca un singur element. Utilizatorul poate atinge de două ori pentru a activa întreaga carte sau poate configura rotorul pentru navigare în interior. Recomandat pentru UICollectionViewCell și UITableViewCell.

Android: atributele de direcție a focalizării

În Android, TalkBack folosește de asemenea ordinea geometrică, dar prioritate au atributele explicite nextFocus*. Aceste atribute se setează în XML sau programatic:

AtributDestinațieExemplu
nextFocusDownElement la navigarea în jos@+id/field_email
nextFocusUpElement la navigarea în sus@+id/field_name
nextFocusLeftElementul din stânga@+id/btn_back
nextFocusRightElementul din dreapta@+id/btn_next

Exemplu pentru formularul de înregistrare:

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

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

Pentru RecyclerView ordinea focalizării este dinamică — este determinată de adaptor. Dacă celulele au o structură complexă, setați descendantFocusability = „beforeDescendants” și definiți ordinea în nodul elementului de listă. Pentru Jetpack Compose, ordinea focalizării se setează prin Modifier.focusOrder() și FocusOrder. Prioritate: previous (copil), next (următor), custom key.

TouchDelegate, zona de atingere și aria de focalizare

Dacă un element este prea mic pentru focalizare (mai mic de 44 pt), măriți zona de atingere prin TouchDelegate în iOS sau minWidth/minHeight în Android. Conform Google Material Design, 2024, aria minimă de atingere este de 48×48 dp. VoiceOver și TalkBack se focalizează pe bounding box-ul elementului. Elementele mai mici de 30 pt pot fi inaccesibile pentru focalizarea prin gesturi — utilizatorul nu poate atinge fizic cu degetul.

Încălcări tipice WCAG 2.4.3

Focalizare săritoare — când după o acțiune (de exemplu, ștergerea unui element) focalizarea se mută la începutul listei sau pe butonul de sistem „Înapoi”. Utilizatorul VoiceOver pierde contextul. Soluție: mutarea programatică a focalizării pe elementul cel mai apropiat de cel șters.

Focalizare invizibilă — elementul primește focalizare, dar nu există un indicator vizual (utilizatorii de tastatură nu văd unde se află). În iOS, verificați UIAccessibility.isVoiceOverRunning pentru indicatoare personalizate. Conform Deque University, 2024, focalizarea invizibilă este a doua cea mai frecventă cauză de eșec a auditului de accesibilitate.

Ferestre modale — focalizarea rămâne pe conținutul de fundal după deschiderea unei ferestre modale. În iOS, vizualizarea modală capturează automat focalizarea dacă este setat modalPresentationStyle = .pageSheet. În Android, utilizați setFocusable(true) pe containerul dialogului.

Captura de focalizare (focus trap)

Problema inversă: focalizarea rămâne blocată în interiorul ferestrei modale și nu poate ieși (cu excepția închiderii). Acest lucru este permis doar pentru ferestrele modale — utilizatorul trebuie să închidă în mod conștient fereastra. Pentru ecranele obișnuite, captura de focalizare este o eroare critică. Soluție: asigurați-vă că ultimul element al ferestrei modale (butonul „Închide”) transmite focalizarea înapoi.

Ecrane personalizate și focalizare programatică

Pentru ecranele personalizate (hărți, pânze, jocuri), ordinea geometrică automată nu se aplică. Dezvoltatorul trebuie să construiască manual arborele de accesibilitate. În iOS, pentru aceasta se suprascrie metoda UIAccessibilityContainer.

Exemplu pentru o pânză personalizată:

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

    override var accessibilityElements: [Any]? {
        get {
            // Sortăm formele după indicele Z, nu după geometrie
            return shapes.sorted { $0.zIndex < $1.zIndex }
        }
        set {}
    }
}

În Android, pentru o View personalizată, suprascrieți onInitializeAccessibilityNodeInfo:

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

Pentru listele dinamice (chat, flux de știri), după adăugarea unui element, apelați mutarea focalizării pe primul element nou. În iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). În Android: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).

AccessibilityFrame și geometria focalizării

iOS determină automat aria de focalizare pe baza cadrului elementului. Dacă elementul are o transformare (transform, rotation), VoiceOver se poate focaliza pe o arie incorectă. Setați explicit accessibilityFrame în coordonatele ecranului: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Aceasta garantează că VoiceOver va evidenția aria corectă.

UIKit Dynamics și accesibilitatea

Pentru ecranele animate (UIKit Dynamics, Lottie, SpriteKit), focalizarea programatică este deosebit de importantă. VoiceOver nu poate construi un arbore de accesibilitate pentru elementele în mișcare dinamică. Setați isAccessibilityElement = false pe containerele de animație și true doar pe elementele interactive din interior.

Testarea ordinii de focalizare

Testare manuală: activați VoiceOver (iOS) sau TalkBack (Android), glisați cu degetul la dreapta prin întreaga secvență. Focalizarea trebuie să urmeze ordinea vizuală — de la stânga la dreapta, de sus în jos. Fiecare element interactiv trebuie să primească focalizarea exact o dată.

Testarea automatizată este dificilă, dar posibilă:

swift
func testKeyboardFocusOrder() {
    let app = XCUIApplication()
    app.launch()
    app.textFields["Email"].tap()
    // Tab — doar cu tastatura hardware
}

Pentru Android, utilizați 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()))
}

Metoda cea mai fiabilă — testul de scenariu UI: completați formularul pas cu pas (Email → Parolă → Trimite), verificând că fiecare pas se finalizează cu succes. Dacă ordinea focalizării este încălcată, scenariul va eșua la încercarea de a interacționa cu un element în afara focalizării.

Xcode Accessibility Inspector pentru depanare

Instrumentul Accessibility Inspector din Xcode afișează arborele complet de accesibilitate. Puteți parcurge elementele în ordinea VoiceOver și vedea calea exactă de focalizare. Utilizați fila „Audit” pentru căutarea automată a încălcărilor Focus Order.

Întrebări frecvente

Ce este WCAG 2.4.3 și care sunt cerințele pentru focalizare?

WCAG 2.4.3 (Focus Order) este un criteriu de succes de nivel A. Cere ca ordinea focalizării să păstreze sensul conținutului în timpul navigării secvențiale. Încălcarea este considerată critică și blochează certificarea.

Cum se setează ordinea focalizării pentru elementele ascunse în spatele animației?

Elementele ascunse trebuie să aibă isAccessibilityElement = false în iOS sau visibility = gone/invisible în Android. La apariție, mutați programatic focalizarea prin UIAccessibility.post(notification: .layoutChanged).

Cu ce diferă focalizarea în iOS de Android?

iOS gestionează prin accessibilityElements și shouldGroupAccessibilityElement, Android — prin atributele nextFocus* și AccessibilityNodeInfo. Principiul este același: ordine geometrică implicită cu posibilitate de suprascriere.

Ce fac dacă RecyclerView are o ordine incorectă?

Setați descendantFocusability = „beforeDescendants” pe elementul rădăcină și configurați ordinea în adaptor prin onInitializeAccessibilityNodeInfo pentru fiecare celulă.

Cum verific focalizarea fără VoiceOver?

Conectați tastatura hardware prin Bluetooth sau USB. În iOS, apăsați Tab pentru a muta focalizarea. În Android, activați TalkBack și utilizați tastele Tab și săgețile.

Concluzii

  • Focus Order — secvența de parcurgere a elementelor la navigarea cu tastatura sau cititor de ecran; bazată pe WCAG 2.4.3
  • Focalizarea trebuie să urmeze ordinea vizuală (de la stânga la dreapta, de sus în jos) — automat în VoiceOver și TalkBack
  • În iOS, ordinea se reglează prin accessibilityElements și shouldGroupAccessibilityElement
  • În Android se folosesc atributele nextFocusDown, nextFocusUp, nextFocusLeft, nextFocusRight
  • Ecranele personalizate (hărți, pânze) necesită gestionare programatică a focalizării prin UIAccessibilityPostNotification
  • Încălcarea ordinii — eroare critică WCAG 2.4.3; utilizatorii pierd contextul și nu pot finaliza scenariul
  • Testați focalizarea prin gesturi VoiceOver/TalkBack, tastatură hardware și scenarii automatizate

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și