Il Focus Order è la sequenza in cui gli elementi dell’interfaccia ricevono il focus durante la navigazione con una tastiera, Switch Control, VoiceOver o TalkBack. Nelle applicazioni mobili, l’ordine del focus determina come l’utente si sposta tra i controlli tramite gesti o pulsanti. Secondo W3C WCAG 2.2, Success Criterion 2.4.3, 2023, il focus deve seguire un ordine logico che preservi il significato del contenuto. La violazione di questo principio è una delle cause più comuni di fallimento di un audit di accessibilità.
Punti chiave
Focus Order è la sequenza in cui l’utente si sposta tra gli elementi interattivi utilizzando metodi di input alternativi: tastiera (Tab), Switch Control (passo dopo passo), VoiceOver (scorrere a destra/sinistra) o TalkBack. A differenza di un mouse o schermo tattile, dove l’utente seleziona direttamente un elemento, la navigazione tramite focus è lineare — ogni passo sposta il focus all’elemento successivo.
Secondo Apple HIG, 2024, VoiceOver utilizza l’ordine degli elementi nell’albero di accessibilità, che viene costruito in base al posizionamento visivo: angolo superiore sinistro → angolo inferiore destro. Se lo schermo ha un layout complesso (colonne, Grid, ZStack), l’albero potrebbe non corrispondere all’ordine visivo.
Principio WCAG 2.4.3: “Se una pagina web può essere navigata sequenzialmente attraverso le sezioni e l’ordine del focus influisce sul significato, allora il focus deve seguire un ordine che preservi il significato e l’operabilità”. Eccezione: contenuto dinamico dove il focus può saltare per attirare l’attenzione (avvisi, finestre modali).
Un utente di Switch Control (persone con disabilità motorie) si sposta automaticamente tra gli elementi — ciclo dopo ciclo. Se l’ordine è rotto, l’utente impiega 3 volte più tempo per completare il modulo. Secondo Deque University, 2024, un Focus Order corretto riduce il tempo di compilazione del modulo del 60% per gli utenti di tecnologie assistive.
Attenzione particolare — le finestre modali. Dopo l’apertura di un modale, il focus deve spostarsi immediatamente sul primo elemento interattivo all’interno del modale (di solito un pulsante “Chiudi” o “Conferma”). Dopo la chiusura — tornare all’elemento che ha attivato il modale. Questo è un requisito di WCAG 2.4.3 e anche un errore comune.
In iOS, VoiceOver costruisce automaticamente l’ordine basato sulla geometria: gli elementi sono ordinati per Y, poi per X. Per schermi con struttura complessa, questo ordine potrebbe essere errato — lo sviluppatore deve intervenire.
Strumenti principali:
Esempio di impostazione dell’ordine personalizzato per una scheda prodotto:
class ProductCardView: UIView {
let titleLabel = UILabel()
let priceLabel = UILabel()
let buyButton = UIButton()
override var accessibilityElements: [Any]? {
get {
return [titleLabel!, priceLabel!, buyButton!]
}
set {}
}
}
Per lo spostamento programmatico del focus dopo un’azione:
UIAccessibility.post(
notification: .layoutChanged,
argument: newlyAddedItem
)
La proprietà shouldGroupAccessibilityElement è utile per le schede nelle collezioni. Se impostata su true sulla scheda padre, VoiceOver percepisce l’intera scheda come un unico elemento. L’utente può toccare due volte per attivare l’intera scheda, o configurare il rotore per la navigazione interna. Raccomandato per UICollectionViewCell e UITableViewCell.
In Android, TalkBack utilizza anch’esso l’ordine geometrico, ma viene data priorità agli attributi espliciti nextFocus*. Questi attributi vengono impostati in XML o programmaticamente:
| Attributo | Scopo | Esempio |
|---|---|---|
| nextFocusDown | Elemento durante la navigazione verso il basso | @+id/field_email |
| nextFocusUp | Elemento durante la navigazione verso l’alto | @+id/field_name |
| nextFocusLeft | Elemento a sinistra | @+id/btn_back |
| nextFocusRight | Elemento a destra | @+id/btn_next |
Esempio per un modulo di registrazione:
<EditText
android:id="@+id/field_email"
android:nextFocusDown="@+id/field_password" />
<EditText
android:id="@+id/field_password"
android:nextFocusDown="@+id/btn_submit" />
Per RecyclerView, l’ordine del focus è dinamico — determinato dall’adattatore. Se le celle hanno una struttura complessa, impostate descendantFocusability = “beforeDescendants” e definite l’ordine nel nodo dell’elemento dell’elenco. Per Jetpack Compose, l’ordine del focus viene impostato tramite Modifier.focusOrder() e FocusOrder. Priorità: previous (figlio), next (successivo), chiave personalizzata.
Se un elemento è troppo piccolo per il focus (meno di 44pt), aumentate l’area di impatto tramite TouchDelegate in iOS o minWidth/minHeight in Android. Secondo Google Material Design, 2024, l’area tattile minima è di 48×48dp. VoiceOver e TalkBack si concentrano sul riquadro di delimitazione dell’elemento. Gli elementi inferiori a 30pt potrebbero essere inaccessibili al focus gestuale — l’utente non può fisicamente toccarli.
Focus saltellante — quando dopo un’azione (ad esempio, eliminare un elemento) il focus si sposta all’inizio dell’elenco o al pulsante “Indietro” di sistema. L’utente di VoiceOver perde il contesto. Soluzione: spostare programmaticamente il focus sull’elemento più vicino a quello eliminato.
Focus invisibile — un elemento riceve il focus ma non c’è indicatore visivo (gli utenti della tastiera non vedono dove si trovano). In iOS, verificate UIAccessibility.isVoiceOverRunning per indicatori personalizzati. Secondo Deque University, 2024, il focus invisibile è la seconda causa più comune di fallimento di un audit di accessibilità.
Modali — il focus rimane sul contenuto di sfondo dopo l’apertura di un modale. In iOS, la vista modale cattura automaticamente il focus se modalPresentationStyle = .pageSheet è impostato. In Android, utilizzate setFocusable(true) sul contenitore del dialogo.
Il problema inverso: il focus rimane bloccato all’interno di un modale e non può uscire (tranne chiudendolo). Questo è accettabile solo per finestre modali — l’utente deve chiudere intenzionalmente la finestra. Per schermi normali, la trappola del focus è un errore critico. Soluzione: assicuratevi che l’ultimo elemento del modale (il pulsante “Chiudi”) restituisca il focus.
Per schermi personalizzati (mappe, canvas, giochi) l’ordine geometrico automatico non è applicabile. Lo sviluppatore deve costruire l’albero di accessibilità manualmente. In iOS, il metodo UIAccessibilityContainer viene sovrascritto a questo scopo.
Esempio per un canvas personalizzato:
class CanvasView: UIView {
var shapes: [ShapeView] = []
override var accessibilityElements: [Any]? {
get {
// Ordina le forme per Z-index, non per geometria
return shapes.sorted { $0.zIndex < $1.zIndex }
}
set {}
}
}
In Android, per una View personalizzata, sovrascrivete onInitializeAccessibilityNodeInfo:
override fun onInitializeAccessibilityNodeInfo(
info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(info)
info.addChild(firstElement)
info.addChild(secondElement)
info.isFocusable = true
}
Per elenchi dinamici (chat, feed di notizie), dopo aver aggiunto un elemento, spostate il focus sul primo nuovo elemento. In iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). In Android: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).
iOS determina automaticamente l’area del focus in base al frame dell’elemento. Se un elemento ha una trasformazione (transform, rotation), VoiceOver potrebbe concentrarsi sull’area sbagliata. Impostate esplicitamente accessibilityFrame in coordinate dello schermo: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Ciò garantisce che VoiceOver evidenzi l’area corretta.
Per schermi animati (UIKit Dynamics, Lottie, SpriteKit), il focus programmatico è particolarmente importante. VoiceOver non può costruire un albero di accessibilità per elementi in movimento dinamico. Impostate isAccessibilityElement = false sui contenitori di animazione e true solo sugli elementi interattivi all’interno.
Test manuale: attivate VoiceOver (iOS) o TalkBack (Android), scorrete verso destra attraverso l’intera sequenza. Il focus deve seguire l’ordine visivo — da sinistra a destra, dall’alto in basso. Ogni elemento interattivo deve ricevere il focus esattamente una volta.
Test automatizzati sono difficili ma possibili:
func testKeyboardFocusOrder() {
let app = XCUIApplication()
app.launch()
app.textFields["Email"].tap()
// Tab — solo con tastiera hardware
}
Per Android, utilizzate il Accessibility Testing Framework:
@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()))
}
Il metodo più affidabile è un test di scenario dell’interfaccia: compilate il modulo passo dopo passo (Email → Password → Invia), verificando che ogni passo venga completato con successo. Se l’ordine del focus è rotto, lo scenario fallirà quando si tenta di interagire con un elemento fuori dal focus.
Lo strumento Accessibility Inspector in Xcode mostra l’albero di accessibilità completo. Potete scorrere gli elementi nell’ordine di VoiceOver e vedere il percorso esatto del focus. Utilizzate la scheda “Audit” per il rilevamento automatico delle violazioni di Focus Order.
Domande frequenti
WCAG 2.4.3 (Focus Order) è un criterio di successo di livello A. Richiede che l’ordine del focus preservi il significato del contenuto durante la navigazione sequenziale. La violazione è considerata critica e blocca la certificazione.
Gli elementi nascosti devono avere isAccessibilityElement = false in iOS o visibility = gone/invisible in Android. Quando appaiono, spostate programmaticamente il focus tramite UIAccessibility.post(notification: .layoutChanged).
iOS gestisce tramite accessibilityElements e shouldGroupAccessibilityElement, Android tramite attributi nextFocus* e AccessibilityNodeInfo. Il principio è lo stesso: ordine geometrico predefinito con possibilità di sovrascrittura.
Impostate descendantFocusability = “beforeDescendants” sull’elemento radice e configurate l’ordine nell’adattatore tramite onInitializeAccessibilityNodeInfo per ogni cella.
Collegate una tastiera fisica tramite Bluetooth o USB. Su iOS premete Tab per spostare il focus. Su Android attivate TalkBack e utilizzate il tasto Tab e i tasti freccia.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche