Lliçó 5 de 10 · 14 min de lectura · Revisada el 26/10/2026
Navegació, focus i estructura de pantalles: títols, ordre, diàlegs i teclat extern
Estàs llegint una lliçó oberta. Matricula't per fer els tests i els exercicis, desar el teu progrés i aconseguir el certificat.
Matricula-m'hi · nivell 6 (119 €)A les lliçons d'iOS i Android vas veure com descriure cada control: nom, rol, estat i accions. Però una aplicació no és un conjunt de controls solts, sinó un recorregut entre pantalles, fulls, diàlegs i menús. Per a qui fa servir VoiceOver, TalkBack, Switch Control o un teclat extern, la pregunta constant és «on soc i on és el focus?». Aquesta lliçó tracta d'aquesta capa: títols de pantalla, ordre de recorregut, encapçalaments, gestió del focus en navegar i en obrir o tancar finestres modals, i funcionament amb teclat. És, a la pràctica, la font de molts dels errors més greus d'una auditoria mòbil, perquè bloquegen tasques completes.
Dos focus diferents: el d'accessibilitat i el d'entrada
Al web només hi ha un focus. Al mòbil en conviuen dos, i confondre'ls és l'origen de molts errors:
- Focus d'accessibilitat: l'element que el lector de pantalla està llegint, marcat amb un requadre (el «cursor de VoiceOver» o el rectangle verd de TalkBack). Es mou amb els gestos de lliscar i es pot situar sobre qualsevol element accessible, inclosos els textos no interactius.
- Focus d'entrada: l'element que rep les pulsacions d'un teclat físic o de Full Keyboard Access, i el camp on escriu el teclat en pantalla. Només el reben els elements enfocables (controls i camps).
A Android la diferència és explícita: requestFocus() mou el focus d'entrada, mentre que el focus d'accessibilitat es mou amb performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null). A Compose, un FocusRequester mou el focus d'entrada; si el que necessites és que TalkBack llegeixi un element concret, comprova-ho sempre amb TalkBack actiu, perquè no n'hi ha prou que el camp tingui el cursor. A iOS, el focus de VoiceOver es dirigeix amb les notificacions .screenChanged i .layoutChanged (UIKit) o amb @AccessibilityFocusState (SwiftUI), i el de teclat amb el sistema de focus d'UIKit (UIFocusSystem) o @FocusState a SwiftUI.
Punt clau
En dissenyar un canvi de pantalla o l'aparició d'un diàleg, decideix explícitament on ha de quedar cada focus. Si no ho decideixes tu, ho decideix el sistema, i de vegades el deixa en un element que ja no existeix o darrere de la finestra que acabes d'obrir.
Títols de pantalla i encapçalaments
El criteri 2.4.2 Pàgina titulada no es trasllada de manera literal: WCAG2ICT l'aplica al programari en conjunt i l'EN 301 549 v3.2.1 (PDF, s'obre en una finestra nova) el deixa buit al capítol 11. Tot i així, que cada pantalla tingui un títol que la identifiqui és la pràctica esperada i la manera de saber on s'és. No n'hi ha prou que es vegi: la tecnologia de suport l'ha d'anunciar en arribar-hi.
- iOS:
UINavigationControlleriNavigationStackanuncien el canvi i VoiceOver situa el focus al principi de la nova pantalla. Fes servirnavigationItem.titleo.navigationTitle("Les meves cites")sempre, encara que la barra s'amagui per disseny. En les transicions personalitzades, publicaUIAccessibility.post(notification: .screenChanged, argument: tituloLabel). - Android (Views): TalkBack anuncia el títol de l'activitat en canviar de finestra. Amb una sola activitat i diversos fragments, actualitza el títol o fes servir
ViewCompat.setAccessibilityPaneTitle(vista, "Les meves cites")al contenidor del fragment perquè el canvi s'anunciï. - Compose: marca el contenidor de cada destinació amb
Modifier.semantics { paneTitle = "Les meves cites" }i fes servir unTopAppBaramb títol visible.
Dins de la pantalla, els encapçalaments (.header a iOS, heading() a Compose, accessibilityHeading a Views) permeten saltar per seccions amb el rotor de VoiceOver o els controls de lectura de TalkBack. Són l'equivalent funcional dels skip links (enllaços per saltar blocs) del web: en una pantalla de fitxa amb deu blocs, marcar cada títol de secció com a encapçalament estalvia desenes de gestos.
Ordre de recorregut
Els lectors recorren els elements en un ordre calculat a partir de la jerarquia i la posició a la pantalla: de dalt a baix i, a cada fila, en el sentit de lectura. Aquest ordre falla amb disposicions en columnes, targetes amb elements superposats o botons flotants. Els criteris afectats són l'1.3.2 Seqüència significativa i el 2.4.3 Ordre del focus.
| Necessitat | iOS | Android |
|---|---|---|
| Definir l'ordre dels fills | accessibilityElements (UIKit), .accessibilitySortPriority (SwiftUI) | accessibilityTraversalBefore/After (Views), traversalIndex (Compose) |
| Recórrer un bloc sencer abans de sortir-ne | shouldGroupAccessibilityChildren, .accessibilityElement(children: .contain) | isTraversalGroup = true (Compose); a Views, un ViewGroup contenidor comú, perquè el recorregut segueix la jerarquia |
| Moure el focus després d'un canvi | .layoutChanged amb argument, @AccessibilityFocusState | ACTION_ACCESSIBILITY_FOCUS, live region o paneTitle |
| Amagar el que hi ha al darrere | accessibilityViewIsModal, .isModal | importantForAccessibility="noHideDescendants", Dialog |
Corregeix l'ordre amb aquestes API només quan la disposició no es pugui reorganitzar: la primera opció és que l'ordre del codi coincideixi amb l'ordre visual lògic. Un cas típic és el botó flotant d'acció («Nova incidència»): visualment és a baix a la dreta, però conceptualment és una acció principal; col·loca'l al recorregut just després del títol o del contingut que el motiva, no al final d'una llista de cent elements.
Infografia · Procés
Com gestionar un canvi de pantalla o un diàleg
Cinc passos perquè qui fa servir VoiceOver, TalkBack o el teclat sàpiga sempre on és
- Pas 1: Anunciar el títolLa pantalla o el diàleg té un títol que el lector anuncia en arribar-hi
- Pas 2: Col·locar el focusAl títol o al primer element lògic, mai al final ni al darrere
- Pas 3: Amagar el fonsAmb el diàleg obert, el que queda al darrere no es pot recórrer
- Pas 4: Permetre tancarBotó visible, gest d'escapament de VoiceOver i botó Enrere d'Android
- Pas 5: Retornar el focusEn tancar, el focus torna al control que va obrir el diàleg
Llegir la infografia com a text
Procés de cinc passos en seqüència per gestionar un canvi de pantalla o l'obertura d'un diàleg en una aplicació. Pas 1, anunciar el títol: la nova pantalla o el diàleg s'identifica amb un títol que el lector de pantalla anuncia en arribar-hi. Pas 2, col·locar el focus: el focus va al títol o al primer element lògic, mai al final ni al darrere. Pas 3, amagar el fons: mentre el diàleg és obert, el que queda al darrere no es pot recórrer. Pas 4, permetre tancar: amb un botó visible, amb el gest d'escapament de VoiceOver i amb el botó Enrere d'Android. Pas 5, retornar el focus: en tancar, el focus torna al control que va obrir el diàleg o a un altre lloc lògic.
Diàlegs, fulls inferiors i menús
Una finestra modal accessible compleix quatre condicions: el focus hi entra en obrir-se, el contingut del darrere queda inaccessible mentre és oberta, es pot tancar sense gestos especials i, en tancar-se, el focus torna a un lloc lògic (normalment el control que la va obrir). Els components del sistema (UIAlertController, .sheet, .confirmationDialog, AlertDialog, ModalBottomSheet, DropdownMenu) ho compleixen gairebé tot de sèrie. Els problemes arriben amb les capes personalitzades: una vista superposada dins de la mateixa pantalla que, per al lector, no és modal.
// UIKit: capa personalitzada que es comporta com a modal
final class FiltroOverlay: UIView {
override func didMoveToSuperview() {
super.didMoveToSuperview()
accessibilityViewIsModal = true // ignora el que hi ha al darrere
UIAccessibility.post(notification: .screenChanged, argument: tituloLabel)
}
// Gest d'escapament de VoiceOver (dos dits en «Z»)
override func accessibilityPerformEscape() -> Bool {
cerrar(); return true
}
}
// SwiftUI: capa pròpia
PanelFiltros()
.accessibilityAddTraits(.isModal)
.accessibilityAction(.escape) { mostrarFiltros = false } A Android, si la capa és una vista dins de la mateixa finestra, marca el contingut del fons amb importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS mentre sigui oberta i restaura'l en tancar; gestiona el botó Enrere del sistema (OnBackPressedCallback o BackHandler a Compose) per tancar-la. A Compose, la via segura és fer servir Dialog o ModalBottomSheet, que creen la seva pròpia finestra; si construeixes una capa a mà, aplica Modifier.clearAndSetSemantics { } al contingut del fons mentre sigui oberta.
Error freqüent
Un full inferior personalitzat amb els filtres de cerca s'obre sobre la llista, però TalkBack continua recorrent la llista que queda al darrere: l'usuari sent resultats en lloc de filtres i no sap que hi ha un full obert. En tancar-lo amb «Aplica», el focus es perd i torna al principi de la pantalla. Incompleix el 2.4.3 Ordre del focus i, segons el cas, l'1.3.2 i el 4.1.2. La correcció: un component modal del sistema o una capa amb el fons amagat, un títol anunciat en obrir i el focus retornat al botó «Filtres» en tancar.
Teclat extern i focus visible
Moltes persones amb discapacitat motriu fan servir el mòbil o la tauleta amb un teclat Bluetooth o amb un commutador que l'emula. A iOS, Full Keyboard Access (Configuració > Accessibilitat > Teclats) permet moure's amb Tab i les fletxes i activar amb la barra espaiadora; a Android, Tab i les fletxes mouen el focus d'entrada i Retorn activa. S'apliquen els mateixos criteris que al web:
- 2.1.1 Teclat i 2.1.2 Sense paranys per al focus del teclat: tot control és abastable i es pot sortir de qualsevol component (un mapa, un reproductor, un camp de text multilínia).
- 2.4.7 Focus visible: els components estàndard dibuixen l'indicador; als controls propis cal pintar-lo (estat
focuseda Views,onFocusChangedoModifier.focusableamb indicació a Compose,isFocusedaUIFocusEnvironment). - 2.4.11 Focus no ocult (mínim): l'element amb el focus no queda tapat completament per barres fixes, bàners o el mateix teclat en pantalla. Desplaça el contingut perquè el camp actiu quedi a la vista.
A Compose, Modifier.focusProperties { next = siguiente } i els grups de focus permeten ajustar el recorregut de teclat quan l'ordre per defecte no serveix; a Views, nextFocusDown, nextFocusForward i similars.
Prova-ho tu
Tria una aplicació que facis servir cada dia (el teu banc, el transport de la teva ciutat). Activa VoiceOver o TalkBack i obre un menú, un filtre o un diàleg de confirmació. Comprova tres coses: s'anuncia el títol en obrir-se?, pots arribar amb gestos de lliscar al que hi ha al darrere?, on queda el focus en tancar-lo? Anota'n el resultat; el faràs servir al cas pràctic.
Resum
- Al mòbil hi ha dos focus, el d'accessibilitat i el d'entrada; decideix on queda cadascun a cada canvi de pantalla i comprova el resultat amb el lector real.
- Cada pantalla té un títol que s'anuncia en arribar-hi (pràctica lligada al 2.4.2):
navigationTitle, títol d'activitat,paneTitle; els encapçalaments permeten saltar per seccions. - L'ordre de recorregut segueix la lògica de la tasca (1.3.2, 2.4.3); corregeix-lo amb les API d'ordre només si no pots reorganitzar la disposició.
- Una capa modal rep el focus, amaga el fons, es tanca amb el gest d'escapament o el botó Enrere i retorna el focus al control que la va obrir.
- Amb teclat extern s'apliquen el 2.1.1, el 2.1.2, el 2.4.7 i el 2.4.11: tot abastable, sense paranys i amb un focus visible que res no tapa.
Portes 8 lliçons d'aquest curs: que no es perdin
Crea el teu compte i desa el que ja has llegit i segueix el curs amb tot:
- El test d'aquesta lliçó (3 preguntes) per comprovar el que has après
- Exercicis pràctics amb pàgines reals
- El teu progrés desat: continues on ho vas deixar, des de qualsevol dispositiu
- Constància del curs amb les hores i certificat del nivell 6 quan aprovis l'examen
Entres amb el teu compte de Google o només amb el teu correu electrònic. No cal contrasenya.
Matricula-m'hi · nivell 6 (119 €)