A Focus Order az a sorrend, amelyben az interfész elemei fókuszt kapnak a billentyűzettel, Switch Control-lal, VoiceOver-rel vagy TalkBack-kel történő navigáció során. A mobilalkalmazásokban a fókusz sorrendje határozza meg, hogyan mozog a felhasználó a vezérlők között gesztusokkal vagy gombokkal. A W3C WCAG 2.2, Success Criterion 2.4.3, 2023 szerint a fókusznak logikus sorrendben kell haladnia, megőrizve a tartalom jelentését. Ennek az elvnek a megsértése az akadálymentességi audit bukásának egyik gyakori oka.
Főbb pontok
A Focus Order az a sorrend, amelyben a felhasználó alternatív beviteli módokkal mozog az interaktív elemek között: billentyűzet (Tab), Switch Control (lépésről lépésre), VoiceOver (jobbra/balra gesztus) vagy TalkBack. Az egértől vagy érintőképernyőtől eltérően, ahol a felhasználó közvetlenül választ ki egy elemet, a fókusznavigáció lineáris — minden lépés a következő elemre viszi a fókuszt.
A Apple HIG, 2024 szerint a VoiceOver az akadálymentességi fa elemeinek sorrendjét használja, amely a vizuális elhelyezés alapján épül fel: bal felső sarok → jobb alsó sarok. Ha a képernyő összetett elrendezést tartalmaz (oszlopok, Grid, ZStack), a fa nem feltétlenül egyezik a vizuális sorrenddel.
A WCAG 2.4.3 elve: „Ha egy weboldal sorrendben bejárható szakaszonként, és a fókusz sorrendje befolyásolja a jelentést, akkor a fókusznak a jelentést és a kezelhetőséget megőrző sorrendben kell haladnia”. Kivétel: dinamikus tartalom, ahol a fókusz ugorhat a figyelem felkeltése érdekében (figyelmeztetések, modális ablakok).
A Switch Control felhasználója (mozgáskorlátozott emberek) automatikusan mozog az elemek között — ciklusról ciklusra. Ha a sorrend megszakad, a felhasználó 3-szor több időt tölt egy űrlap kitöltésével. A Deque University, 2024 szerint a helyes Focus Order 60%-kal csökkenti az űrlapkitöltési időt a segítő technológiát használó felhasználók számára.
Külön figyelmet érdemelnek a modális ablakok. A modális ablak megnyitása után a fókusznak azonnal az első interaktív elemre kell kerülnie a modálban (általában a „Bezárás” vagy „Megerősítés” gombra). Bezárás után — vissza arra az elemre, amely a modális ablakot megnyitotta. Ez a WCAG 2.4.3 követelménye, és egyben gyakori hiba.
iOS-ben a VoiceOver automatikusan építi fel a sorrendet a geometria alapján: az elemeket Y, majd X szerint rendezi. Az összetett szerkezetű képernyőknél ez a sorrend hibás lehet — a fejlesztőnek be kell avatkoznia.
A fő eszközök:
Példa egyedi sorrend beállítására termékkártyához:
class ProductCardView: UIView {
let titleLabel = UILabel()
let priceLabel = UILabel()
let buyButton = UIButton()
override var accessibilityElements: [Any]? {
get {
return [titleLabel!, priceLabel!, buyButton!]
}
set {}
}
}
A fókusz programozott mozgatásához művelet után:
UIAccessibility.post(
notification: .layoutChanged,
argument: newlyAddedItem
)
A shouldGroupAccessibilityElement tulajdonság a gyűjteményekben lévő kártyákhoz hasznos. Ha a szülőkártyán true értéket állítasz be, a VoiceOver az egész kártyát egyetlen elemként érzékeli. A felhasználó dupla érintéssel aktiválhatja az egész kártyát, vagy beállíthatja a rotort a benne való navigációhoz. UICollectionViewCell és UITableViewCell esetén ajánlott.
Androidban a TalkBack is a geometriai sorrendet használja, de az explicit nextFocus* attribútumok kapnak elsőbbséget. Ezeket XML-ben vagy programozottan lehet megadni:
| Attribútum | Funkció | Példa |
|---|---|---|
| nextFocusDown | Elem lefelé navigáláskor | @+id/field_email |
| nextFocusUp | Elem felfelé navigáláskor | @+id/field_name |
| nextFocusLeft | Elem a bal oldalon | @+id/btn_back |
| nextFocusRight | Elem a jobb oldalon | @+id/btn_next |
Példa regisztrációs űrlaphoz:
<EditText
android:id="@+id/field_email"
android:nextFocusDown="@+id/field_password" />
<EditText
android:id="@+id/field_password"
android:nextFocusDown="@+id/btn_submit" />
A RecyclerView esetén a fókusz sorrendje dinamikus — az adapter határozza meg. Ha a cellák összetett szerkezetűek, állítsd be a descendantFocusability = "beforeDescendants" értéket, és add meg a sorrendet a lista elemének csomópontjában. A Jetpack Compose esetén a fókusz sorrendje a Modifier.focusOrder() és a FocusOrder segítségével adható meg. Prioritás: previous (gyermek), next (következő), custom key.
Ha egy elem túl kicsi a fókuszhoz (44pt alatt van), növeld meg az érintési területet a TouchDelegate segítségével iOS-ben vagy a minWidth/minHeight segítségével Androidban. A Google Material Design, 2024 szerint a minimális érintési terület 48×48dp. A VoiceOver és a TalkBack az elem bounding box-ára fókuszál. A 30pt-nál kisebb elemek gesztusos fókuszra nem biztos, hogy elérhetők — a felhasználó fizikailag nem tudja elérni őket az ujjával.
Ugráló fókusz — amikor egy művelet után (például egy elem törlése) a fókusz a lista elejére vagy a rendszer „Vissza” gombjára ugrik. A VoiceOver-felhasználó elveszíti a kontextust. Megoldás: programozottan vidd a fókuszt a törölt elemhez legközelebb eső elemre.
Láthatatlan fókusz — az elem fókuszt kap, de nincs vizuális jelzés (a billentyűzet-használók nem látják, hol vannak). iOS-ben az UIAccessibility.isVoiceOverRunning ellenőrzése szükséges az egyedi jelzésekhez. A Deque University, 2024 szerint a láthatatlan fókusz az akadálymentességi audit bukásának második leggyakoribb oka.
Modális ablakok — a fókusz a háttértartalmon marad a modális ablak megnyitása után. iOS-ben a modális nézet automatikusan elkapja a fókuszt, ha a modalPresentationStyle = .pageSheet értéket állították be. Androidban használj setFocusable(true) értéket a párbeszédpanel konténerén.
A fordított probléma: a fókusz beragad a modális ablakban, és nem tud kilépni (a bezáráson kívül). Ez csak a modális ablakoknál megengedett — a felhasználónak tudatosan be kell zárnia az ablakot. A hétköznapi képernyőknél a focus trap kritikus hiba. Megoldás: győződj meg róla, hogy a modális ablak utolsó eleme (a „Bezárás” gomb) visszaadja a fókuszt.
A speciális képernyőknél (térképek, vásznak, játékok) az automatikus geometriai sorrend nem alkalmazható. A fejlesztőnek manuálisan kell felépítenie az akadálymentességi fát. iOS-ben ehhez az UIAccessibilityContainer metódust írják felül.
Példa egyedi vászonhoz:
class CanvasView: UIView {
var shapes: [ShapeView] = []
override var accessibilityElements: [Any]? {
get {
// Az alakzatokat Z-index szerint rendezzük, nem geometria szerint
return shapes.sorted { $0.zIndex < $1.zIndex }
}
set {}
}
}
Androidban egyedi View esetén írd felül az onInitializeAccessibilityNodeInfo metódust:
override fun onInitializeAccessibilityNodeInfo(
info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(info)
info.addChild(firstElement)
info.addChild(secondElement)
info.isFocusable = true
}
A dinamikus listáknál (chat, hírfolyam) elem hozzáadása után vezesd a fókuszt az első új elemre. iOS-ben: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). Androidban: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).
Az iOS automatikusan meghatározza a fókusz területét az elem frame-je alapján. Ha az elem transzformációval rendelkezik (transform, rotation), a VoiceOver rossz területre fókuszálhat. Add meg kifejezetten az accessibilityFrame értékét képernyőkoordinátákban: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Ez garantálja, hogy a VoiceOver a helyes területet emelje ki.
Az animált képernyőknél (UIKit Dynamics, Lottie, SpriteKit) a programozott fókusz különösen fontos. A VoiceOver nem tud akadálymentességi fát építeni a dinamikusan mozgó elemekhez. Állítsd az isAccessibilityElement = false értéket az animációs konténerekre, és csak az interaktív elemekre true értéket.
Kézi tesztelés: kapcsold be a VoiceOver-t (iOS) vagy a TalkBacket (Android), és menj végig a teljes sorrenden jobbra gesztussal. A fókusznak a vizuális sorrendet kell követnie — balról jobbra, felülről lefelé. Minden interaktív elemnek pontosan egyszer kell fókuszt kapnia.
Automatizált tesztelés nehézkes, de lehetséges:
func testKeyboardFocusOrder() {
let app = XCUIApplication()
app.launch()
app.textFields["Email"].tap()
// Tab — csak hardveres billentyűzettel
}
Androidhoz használd az Accessibility Testing Framework-öt:
@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()))
}
A legmegbízhatóbb módszer — forgatókönyv UI-teszt: töltsd ki az űrlapot lépésről lépésre (Email → Jelszó → Küldés), ellenőrizve, hogy minden lépés sikeresen végződik. Ha a fókusz sorrendje megszakad, a forgatókönyv elbukik, amikor a fókuszon kívüli elemmel próbál interakciót létesíteni.
Az Accessibility Inspector eszköz az Xcode-ban megmutatja a teljes akadálymentességi fát. Végigmehetsz az elemeken a VoiceOver sorrendjében, és látod a pontos fókuszútvonalat. Használd az „Audit” fület a Focus Order megsértéseinek automatikus kereséséhez.
Gyakran ismételt kérdések
A WCAG 2.4.3 (Focus Order) — A szintű sikerességi kritérium. Előírja, hogy a fókusz sorrendje megőrizze a tartalom jelentését a sorozatos navigáció során. A megsértést kritikusnak tekintik, és blokkolja a tanúsítást.
A rejtett elemeknek iOS-ben isAccessibilityElement = false értékkel kell rendelkezniük, Androidban pedig visibility = gone/invisible értékkel. Megjelenéskor programozottan mozgasd a fókuszt az UIAccessibility.post(notification: .layoutChanged) segítségével.
Az iOS az accessibilityElements és a shouldGroupAccessibilityElement segítségével irányít, az Android — a nextFocus* attribútumok és az AccessibilityNodeInfo révén. Az elv ugyanaz: alapértelmezés szerint geometriai sorrend, felülírási lehetőséggel.
Állítsd be a descendantFocusability = "beforeDescendants" értéket a gyökérelemen, és az adapterben az onInitializeAccessibilityNodeInfo segítségével konfiguráld a sorrendet minden cellához.
Csatlakoztass hardveres billentyűzetet Bluetooth-on vagy USB-n keresztül. iOS-ben a Tab billentyűvel mozgathatod a fókuszt. Androidban kapcsold be a TalkBacket, és használd a Tab és a nyílbillentyűket.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is