Focus Order adalah urutan di mana elemen antarmuka menerima fokus saat navigasi dengan keyboard, Switch Control, VoiceOver, atau TalkBack. Dalam aplikasi mobile, urutan fokus menentukan bagaimana pengguna berpindah antar kontrol dengan gerakan atau tombol. Menurut W3C WCAG 2.2, Success Criterion 2.4.3, 2023, fokus harus mengikuti urutan logis yang mempertahankan makna konten. Pelanggaran prinsip ini adalah salah satu penyebab umum gagalnya audit aksesibilitas.
Hal-hal utama
Focus Order adalah urutan di mana pengguna berpindah antar elemen interaktif dengan metode input alternatif: keyboard (Tab), Switch Control (langkah demi langkah), VoiceOver (gestur ke kanan/kiri), atau TalkBack. Berbeda dengan mouse atau layar sentuh, di mana pengguna memilih elemen secara langsung, navigasi fokus bersifat linier — setiap langkah memindahkan fokus ke elemen berikutnya.
Menurut Apple HIG, 2024, VoiceOver menggunakan urutan elemen dalam pohon aksesibilitas, yang dibangun berdasarkan penempatan visual: sudut kiri atas → sudut kanan bawah. Jika layar berisi tata letak yang kompleks (kolom, Grid, ZStack), pohon mungkin tidak sesuai dengan urutan visual.
Prinsip WCAG 2.4.3: "Jika halaman web dapat dinavigasi secara berurutan per bagian dan urutan fokus memengaruhi makna, maka fokus harus mengikuti urutan yang mempertahankan makna dan kemungkinan pengoperasian". Pengecualian: konten dinamis di mana fokus dapat melompat untuk menarik perhatian (peringatan, jendela modal).
Pengguna Switch Control (orang dengan gangguan motorik) berpindah antar elemen secara otomatis — siklus demi siklus. Jika urutan rusak, pengguna menghabiskan waktu 3 kali lebih lama untuk menyelesaikan formulir. Menurut Deque University, 2024, Focus Order yang benar mengurangi waktu pengisian formulir hingga 60% bagi pengguna teknologi bantu.
Perhatian khusus diberikan pada jendela modal. Setelah membuka jendela modal, fokus harus langsung dipindahkan ke elemen interaktif pertama di dalam modal (biasanya tombol "Tutup" atau "Konfirmasi"). Setelah ditutup — kembali ke elemen yang memanggil jendela modal. Ini adalah persyaratan WCAG 2.4.3 sekaligus kesalahan yang umum.
Di iOS, VoiceOver membangun urutan secara otomatis berdasarkan geometri: elemen diurutkan berdasarkan Y, lalu X. Untuk layar dengan struktur kompleks, urutan ini bisa salah — pengembang harus turun tangan.
Alat-alat utama:
Contoh mengatur urutan khusus untuk kartu produk:
class ProductCardView: UIView {
let titleLabel = UILabel()
let priceLabel = UILabel()
let buyButton = UIButton()
override var accessibilityElements: [Any]? {
get {
return [titleLabel!, priceLabel!, buyButton!]
}
set {}
}
}
Untuk pemindahan fokus secara programatik setelah suatu tindakan:
UIAccessibility.post(
notification: .layoutChanged,
argument: newlyAddedItem
)
Properti shouldGroupAccessibilityElement berguna untuk kartu dalam koleksi. Jika disetel true pada kartu induk, VoiceOver menganggap seluruh kartu sebagai satu elemen. Pengguna dapat mengetuk dua kali untuk mengaktifkan seluruh kartu atau mengatur rotor untuk navigasi di dalamnya. Direkomendasikan untuk UICollectionViewCell dan UITableViewCell.
Di Android, TalkBack juga menggunakan urutan geometris, tetapi prioritas diberikan pada atribut eksplisit nextFocus*. Atribut ini diatur dalam XML atau secara programatik:
| Atribut | Fungsi | Contoh |
|---|---|---|
| nextFocusDown | Elemen saat navigasi ke bawah | @+id/field_email |
| nextFocusUp | Elemen saat navigasi ke atas | @+id/field_name |
| nextFocusLeft | Elemen di sebelah kiri | @+id/btn_back |
| nextFocusRight | Elemen di sebelah kanan | @+id/btn_next |
Contoh untuk formulir pendaftaran:
<EditText
android:id="@+id/field_email"
android:nextFocusDown="@+id/field_password" />
<EditText
android:id="@+id/field_password"
android:nextFocusDown="@+id/btn_submit" />
Untuk RecyclerView urutan fokus bersifat dinamis — ditentukan oleh adapter. Jika sel memiliki struktur kompleks, atur descendantFocusability = "beforeDescendants" dan tentukan urutan di simpul elemen daftar. Untuk Jetpack Compose urutan fokus diatur melalui Modifier.focusOrder() dan FocusOrder. Prioritas: previous (anak), next (berikutnya), custom key.
Jika elemen terlalu kecil untuk fokus (kurang dari 44pt), perbesar area sentuh melalui TouchDelegate di iOS atau minWidth/minHeight di Android. Menurut Google Material Design, 2024, area sentuh minimum adalah 48×48dp. VoiceOver dan TalkBack berfokus pada bounding box elemen. Elemen yang lebih kecil dari 30pt mungkin tidak dapat diakses untuk fokus gestur — pengguna secara fisik tidak dapat menjangkaunya dengan jari.
Fokus melompat — ketika setelah suatu tindakan (misalnya menghapus elemen) fokus berpindah ke awal daftar atau ke tombol sistem "Kembali". Pengguna VoiceOver kehilangan konteks. Solusi: pindahkan fokus secara programatik ke elemen yang paling dekat dengan elemen yang dihapus.
Fokus tak terlihat — elemen menerima fokus, tetapi tidak ada indikator visual (pengguna keyboard tidak melihat posisinya). Di iOS periksa UIAccessibility.isVoiceOverRunning untuk indikator khusus. Menurut Deque University, 2024, fokus tak terlihat adalah penyebab paling umum kedua kegagalan audit aksesibilitas.
Jendela modal — fokus tetap pada konten latar belakang setelah membuka jendela modal. Di iOS, tampilan modal otomatis menangkap fokus jika modalPresentationStyle = .pageSheet diatur. Di Android gunakan setFocusable(true) pada kontainer dialog.
Masalah sebaliknya: fokus terjebak di dalam jendela modal dan tidak dapat keluar (kecuali dengan menutupnya). Ini hanya diperbolehkan untuk jendela modal — pengguna harus menutup jendela secara sadar. Untuk layar biasa, focus trap adalah kesalahan kritis. Solusi: pastikan elemen terakhir jendela modal (tombol "Tutup") mengembalikan fokus kembali.
Untuk layar khusus (peta, kanvas, game) urutan geometris otomatis tidak dapat diterapkan. Pengembang harus membangun pohon aksesibilitas secara manual. Di iOS, untuk ini metode UIAccessibilityContainer ditimpa.
Contoh untuk kanvas khusus:
class CanvasView: UIView {
var shapes: [ShapeView] = []
override var accessibilityElements: [Any]? {
get {
// Kami mengurutkan bentuk berdasarkan Z-index, bukan berdasarkan geometri
return shapes.sorted { $0.zIndex < $1.zIndex }
}
set {}
}
}
Di Android untuk View khusus, timpa onInitializeAccessibilityNodeInfo:
override fun onInitializeAccessibilityNodeInfo(
info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(info)
info.addChild(firstElement)
info.addChild(secondElement)
info.isFocusable = true
}
Untuk daftar dinamis (obrolan, umpan berita) setelah menambahkan elemen, panggil pemindahan fokus ke elemen baru pertama. Di iOS: UIAccessibility.post(notification: .layoutChanged, argument: newMessage). Di Android: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED).
iOS secara otomatis menentukan area fokus berdasarkan frame elemen. Jika elemen memiliki transformasi (transform, rotation), VoiceOver dapat berfokus pada area yang salah. Tetapkan accessibilityFrame secara eksplisit dalam koordinat layar: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element). Ini memastikan VoiceOver menyorot area yang benar.
Untuk layar animasi (UIKit Dynamics, Lottie, SpriteKit) fokus programatik sangat penting. VoiceOver tidak dapat membangun pohon aksesibilitas untuk elemen yang bergerak secara dinamis. Atur isAccessibilityElement = false pada kontainer animasi dan hanya true pada elemen interaktif di dalamnya.
Pengujian manual: aktifkan VoiceOver (iOS) atau TalkBack (Android), lakukan gestur ke kanan di seluruh urutan. Fokus harus mengikuti urutan visual — dari kiri ke kanan, dari atas ke bawah. Setiap elemen interaktif harus menerima fokus tepat satu kali.
Pengujian otomatis sulit, tetapi mungkin:
func testKeyboardFocusOrder() {
let app = XCUIApplication()
app.launch()
app.textFields["Email"].tap()
// Tab — hanya dengan keyboard perangkat keras
}
Untuk Android gunakan 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()))
}
Metode paling andal — uji UI skenario: isi formulir langkah demi langkah (Email → Kata sandi → Kirim), memeriksa bahwa setiap langkah berhasil. Jika urutan fokus rusak, skenario gagal saat mencoba berinteraksi dengan elemen di luar fokus.
Alat Accessibility Inspector di Xcode menampilkan pohon aksesibilitas lengkap. Anda dapat menelusuri elemen dalam urutan VoiceOver dan melihat jalur fokus yang tepat. Gunakan tab "Audit" untuk mencari pelanggaran Focus Order secara otomatis.
Pertanyaan yang sering diajukan
WCAG 2.4.3 (Focus Order) — kriteria keberhasilan tingkat A. Mensyaratkan bahwa urutan fokus mempertahankan makna konten saat navigasi berurutan. Pelanggaran dianggap kritis dan memblokir sertifikasi.
Elemen tersembunyi harus memiliki isAccessibilityElement = false di iOS atau visibility = gone/invisible di Android. Saat muncul, pindahkan fokus secara programatik melalui UIAccessibility.post(notification: .layoutChanged).
iOS mengelola melalui accessibilityElements dan shouldGroupAccessibilityElement, Android — melalui atribut nextFocus* dan AccessibilityNodeInfo. Prinsipnya sama: urutan geometris secara default dengan kemungkinan untuk ditimpa.
Atur descendantFocusability = "beforeDescendants" pada elemen akar dan konfigurasikan urutan di adapter melalui onInitializeAccessibilityNodeInfo untuk setiap sel.
Hubungkan keyboard perangkat keras melalui Bluetooth atau USB. Di iOS tekan Tab untuk memindahkan fokus. Di Android aktifkan TalkBack dan gunakan tombol Tab dan panah.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga