Focus Order är den sekvens i vilken gränssnittselement får fokus vid navigering med tangentbord, Switch Control, VoiceOver eller TalkBack. I mobilappar bestämmer fokusordningen hur användaren rör sig mellan kontroller med gester eller knappar. Enligt W3C WCAG 2.2, Success Criterion 2.4.3, 2023 ska fokus följa en logisk ordning som bevarar innehållets mening. Brott mot denna princip är en av de vanligaste orsakerna till underkännande av tillgänglighetsrevisioner.
Huvudpunkter
Focus Order är den sekvens i vilken användaren rör sig mellan interaktiva element med alternativa inmatningsmetoder: tangentbord (Tab), Switch Control (steg för steg), VoiceOver (gest höger/vänster) eller TalkBack. Till skillnad från mus eller pekskärm, där användaren väljer ett element direkt, är fokusnavigering linjär — varje steg flyttar fokus till nästa element.
Enligt Apple HIG, 2024 använder VoiceOver ordningen av element i tillgänglighetsträdet, som bygger på visuell placering: övre vänstra hörnet → nedre högra hörnet. Om skärmen har en komplex layout (kolumner, Grid, ZStack) kan trädet avvika från den visuella ordningen.
WCAG 2.4.3-principen: “Om en webbsida kan navigeras sekventiellt och fokusordningen påverkar betydelsen, ska fokus följa en ordning som bevarar innebörden och användbarheten”. Undantag: dynamiskt innehåll där fokus kan hoppa för att fånga uppmärksamhet (varningar, modala fönster).
En Switch Control-användare (personer med motoriska funktionsnedsättningar) rör sig automatiskt mellan element — cykel efter cykel. Om ordningen bryts lägger användaren 3 gånger mer tid på att fylla i ett formulär. Enligt Deque University, 2024 minskar korrekt fokusordning formulärfyllnadstiden med 60% för användare av hjälpmedelsteknik.
Särskild uppmärksamhet — modala fönster. När ett modalt fönster öppnas ska fokus omedelbart flyttas till det första interaktiva elementet inuti modalen (vanligtvis knappen “Stäng” eller “Bekräfta”). Efter stängning — återgå till elementet som anropade det modala fönstret. Detta är ett krav enligt WCAG 2.4.3 och samtidigt ett vanligt fel.
I iOS bygger VoiceOver automatiskt ordningen baserat på geometri: element sorteras efter Y, sedan efter X. För skärmar med komplex struktur kan denna ordning vara felaktig — utvecklaren måste ingripa.
Grundläggande verktyg:
Exempel på anpassad ordning för en produktkort:
class ProductCardView: UIView {
let titleLabel = UILabel()
let priceLabel = UILabel()
let buyButton = UIButton()
override var accessibilityElements: [Any]? {
get {
return [titleLabel!, priceLabel!, buyButton!]
}
set {}
}
}
För programmatisk förflyttning av fokus efter en åtgärd:
UIAccessibility.post(
notification: .layoutChanged,
argument: newlyAddedItem
)
Egenskapen shouldGroupAccessibilityElement är användbar för kort i samlingar. Om den sätts till true på föräldrakortet uppfattar VoiceOver hela kortet som ett element. Användaren kan dubbeltrycka för att aktivera hela kortet eller ställa in rotorn för navigering inuti. Rekommenderas för UICollectionViewCell och UITableViewCell.
I Android använder TalkBack också geometrisk ordning, men prioritet ges till explicita nextFocus*-attribut. Dessa attribut anges i XML eller programmatiskt:
| Attribut | Syfte | Exempel |
|---|---|---|
| nextFocusDown | Element vid navigering nedåt | @+id/field_email |
| nextFocusUp | Element vid navigering uppåt | @+id/field_name |
| nextFocusLeft | Element till vänster | @+id/btn_back |
| nextFocusRight | Element till höger | @+id/btn_next |
Exempel för registreringsformulär:
<EditText
android:id="@+id/field_email"
android:nextFocusDown="@+id/field_password" />
<EditText
android:id="@+id/field_password"
android:nextFocusDown="@+id/btn_submit" />
För RecyclerView är fokusordningen dynamisk — bestäms av adaptern. Om celler har komplex struktur, ställ in descendantFocusability = “beforeDescendants” och ange ordning i listelementets nod. För Jetpack Compose anges fokusordningen via Modifier.focusOrder() och FocusOrder. Prioritetsordning: previous (underordnat), next (nästa), custom key.
Om ett element är för litet för fokus (mindre än 44pt), öka träffområdet via TouchDelegate i iOS eller minWidth/minHeight i Android. Enligt Google Material Design, 2024 är minimalt beröringsområde 48×48dp. VoiceOver och TalkBack fokuserar på elementets bounding box. Element mindre än 30pt kan vara otillgängliga för gestfokus — användaren kan fysiskt inte träffa dem med fingret.
Hoppande fokus — när fokus efter en åtgärd (t.ex. borttagning av element) flyttas till början av listan eller systemknappen “Tillbaka”. VoiceOver-användaren förlorar sammanhanget. Lösning: programmatiskt flytta fokus till elementet närmast det borttagna.
Osynligt fokus — elementet får fokus men det finns ingen visuell indikator (tangentbordsanvändare ser inte var de befinner sig). I iOS kontrollera UIAccessibility.isVoiceOverRunning för anpassade indikatorer. Enligt Deque University, 2024 är osynligt fokus den näst vanligaste orsaken till underkänd tillgänglighetsrevision.
Modala fönster — fokus stannar kvar på bakgrundsinnehållet efter att ett modalt fönster öppnats. I iOS fångar den modala vyn automatiskt fokus om modalPresentationStyle = .pageSheet är inställt. I Android använd setFocusable(true) på dialogbehållaren.
Omvänt problem: fokus fastnar inuti det modala fönstret och kan inte lämna (förutom stängning). Detta är tillåtet endast för modala fönster — användaren måste medvetet stänga fönstret. För vanliga skärmar är focus trap ett kritiskt fel. Lösning: säkerställ att det sista elementet i det modala fönstret (knappen “Stäng”) skickar tillbaka fokus.
För anpassade skärmar (kartor, canvases, spel) är automatisk geometrisk ordning inte tillämplig. Utvecklaren måste bygga tillgänglighetsträdet manuellt. I iOS åsidosätts metoden UIAccessibilityContainer för detta.
Exempel för anpassad canvas:
class CanvasView: UIView {
var shapes: [ShapeView] = []
override var accessibilityElements: [Any]? {
get {
// Sorterar former efter Z-index, inte efter geometri
return shapes.sorted { $0.zIndex < $1.zIndex }
}
set {}
}
}
I Android för anpassad View, åsidosätt onInitializeAccessibilityNodeInfo:
override fun onInitializeAccessibilityNodeInfo(
info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(info)
info.addChild(firstElement)
info.addChild(secondElement)
info.isFocusable = true
}
För dynamiska listor (chat, nyhetsflöde) efter att ett element lagts till, anropa fokusförflyttning till det första nya elementet. I iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). I Android: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).
iOS bestämmer automatiskt fokusområdet baserat på elementets frame. Om elementet har en transformation (transform, rotation) kan VoiceOver fokusera på fel område. Ange uttryckligen accessibilityFrame i skärmkoordinater: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Detta garanterar att VoiceOver markerar rätt område.
För animerade skärmar (UIKit Dynamics, Lottie, SpriteKit) är programmatiskt fokus särskilt viktigt. VoiceOver kan inte bygga ett tillgänglighetsträd för dynamiskt rörliga element. Ställ in isAccessibilityElement = false på animationsbehållare och true endast på interaktiva element inuti.
Manuell testning: aktivera VoiceOver (iOS) eller TalkBack (Android), svep höger genom hela sekvensen. Fokus ska följa den visuella ordningen — vänster till höger, uppifrån och ned. Varje interaktivt element ska få fokus exakt en gång.
Automatiserad testning är svår men möjlig:
func testKeyboardFocusOrder() {
let app = XCUIApplication()
app.launch()
app.textFields["Email"].tap()
// Tab — endast med externt tangentbord
}
För Android, använd 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()))
}
Den mest pålitliga metoden — UI-test av scenario: fyll i formuläret steg för steg (E-post → Lösenord → Skicka), kontrollera att varje steg slutförs framgångsrikt. Om fokusordningen är bruten misslyckas scenariot vid försök att interagera med ett element utanför fokus.
Verktyget Accessibility Inspector i Xcode visar hela tillgänglighetsträdet. Du kan gå igenom elementen i VoiceOver-ordning och se den exakta fokusvägen. Använd fliken “Audit” för automatisk sökning efter brott mot Focus Order.
Vanliga frågor
WCAG 2.4.3 (Focus Order) — framgångskriterium på nivå A. Kräver att fokusordningen bevarar innehållets mening vid sekventiell navigering. Brott anses vara kritiskt och blockerar certifiering.
Dolda element ska ha isAccessibilityElement = false i iOS eller visibility = gone/invisible i Android. När de visas — flytta fokus programmatiskt via UIAccessibility.post(notification: .layoutChanged).
iOS styr via accessibilityElements och shouldGroupAccessibilityElement, Android — via nextFocus*-attribut och AccessibilityNodeInfo. Principen är densamma: geometrisk ordning som standard med möjlighet till åsidosättande.
Ställ in descendantFocusability = “beforeDescendants” på rotelementet och konfigurera ordningen i adaptern via onInitializeAccessibilityNodeInfo för varje cell.
Anslut ett externt tangentbord via Bluetooth eller USB. I iOS tryck på Tab för att flytta fokus. I Android aktivera TalkBack och använd Tab- och piltangenterna.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också