Accessibility Trait: esensi, apa saja jenisnya dan cara kerjanya dalam pengembangan

Penulis: IT Sectr Diterbitkan: 2026-05-16 Waktu membaca: 9 mnt

Accessibility Trait — adalah properti elemen iOS yang menentukan peran dan perilakunya untuk VoiceOver. Trait memberi tahu pembaca layar bagaimana elemen harus disuarakan dan gerakan apa yang tersedia: apakah itu tombol, header, tautan atau kolom pencarian. Menurut Apple UIAccessibilityTraits, 2024, sistem mendukung 15+ konstanta yang dapat digabungkan dengan mask bit. Trait yang dipilih dengan benar menghemat hingga 50% waktu navigasi bagi pengguna VoiceOver.

Poin Penting

  • Accessibility Trait — peran elemen iOS untuk VoiceOver; ditetapkan melalui konstanta UIAccessibilityTraits
  • Trait dapat digabungkan dengan operator | untuk membuat peran kompleks (tombol + dipilih)
  • Setiap elemen dapat memiliki beberapa trait secara bersamaan, tetapi tidak lebih dari 3-4 untuk menghindari kebingungan
  • Trait yang salah (misalnya StaticText untuk tombol) merusak skenario interaksi: pengguna tidak tahu apakah gerakan tersedia
  • Di Android analognya adalah atribut role dan className di AccessibilityNodeInfo

Apa itu Accessibility Trait

Accessibility Trait — sebuah flag yang dipasang pada elemen UIView untuk menunjukkan peran semantiknya bagi VoiceOver. Trait adalah salah satu dari tiga komponen triad accessibility Apple: Label (nama), Hint (deskripsi), Trait (peran). iOS menggunakan mask bit UIAccessibilityTraits (UInt64), di mana setiap bit sesuai dengan peran tertentu. VoiceOver membaca peran setelah Label dan Hint: “Tombol Kirim. Akan membuka formulir” — “Tombol” ditambahkan berkat trait UIAccessibilityTraitButton.

Secara default, UIButton mendapatkan UIAccessibilityTraitButton, UILabel — UIAccessibilityTraitStaticText, UIImageView — UIAccessibilityTraitImage. Saat menggunakan kontrol khusus, pengembang wajib mengatur trait secara manual. Apple Human Interface Guidelines, 2024, menyebut ini “salah satu langkah paling kritis dalam memastikan accessibility”.

Tanpa trait yang benar, pengguna tidak tahu gerakan mana yang harus diterapkan: sentuhan tunggal (aktivasi tombol), sentuhan ganda (perbesar) atau gerakan gesek (sakelar). Trait menentukan gerakan mana yang akan diaktifkan VoiceOver pada elemen.

Implementasi teknis UIAccessibilityTraits

UIAccessibilityTraits — adalah typealias UInt64. Setiap trait adalah konstanta di mana tepat satu bit diatur. Misalnya UIAccessibilityTraitButton = 0x0000000000000001, UIAccessibilityTraitLink = 0x0000000000000002, UIAccessibilityTraitHeader = 0x0000000000000008. Kombinasi dicapai melalui OR bitwise: 0x0001 | 0x0008 = 0x0009. VoiceOver menganalisis mask dan menentukan perilaku.

Jenis utama trait iOS

iOS menyediakan lebih dari 15 konstanta trait. Mari kita lihat yang utama, yang digunakan dalam 90% skenario:

TraitKonstantaPerilaku VoiceOver
ButtonUIAccessibilityTraitButtonAktivasi dengan sentuhan ganda
HeaderUIAccessibilityTraitHeaderNavigasi cepat melalui header
LinkUIAccessibilityTraitLinkAktivasi sebagai tautan
StaticTextUIAccessibilityTraitStaticTextHanya baca, tanpa aktivasi
SearchFieldUIAccessibilityTraitSearchFieldKolom pencarian dengan perilaku khusus
ImageUIAccessibilityTraitImageGambar, tanpa gerakan aktivasi
SelectedUIAccessibilityTraitSelectedStatus “dipilih”
PlaysSoundUIAccessibilityTraitPlaysSoundMemutar suara saat aktivasi
KeyboardKeyUIAccessibilityTraitKeyboardKeyTombol keyboard
TabBarUIAccessibilityTraitTabBarElemen bilah tab

Konstanta tersedia di UIKit sejak iOS 3.0. Di iOS 14+ dukungan untuk UIAccessibilityTraits di SwiftUI ditambahkan melalui pengubah .accessibilityAddTraits().

Trait langka namun berguna

UIAccessibilityTraitAdjustable — untuk nilai yang dapat disesuaikan (penggeser, pemilih, penggeser volume). VoiceOver memungkinkan geser ke atas/bawah untuk mengubah nilai dengan langkah yang ditentukan melalui accessibilityIncrement dan accessibilityDecrement. UIAccessibilityTraitUpdatesFrequently — untuk elemen dengan nilai yang sering berubah (timer, indikator pemuatan). VoiceOver tidak membaca nilai pada setiap perubahan, tetapi mengambil jeda. UIAccessibilityTraitAllowsDirectInteraction — untuk elemen yang dapat berinteraksi langsung dengan pengguna (keyboard, alat gambar), melewati gerakan VoiceOver.

Menggabungkan trait

Satu elemen dapat memiliki beberapa trait secara bersamaan — kombinasi ditentukan dengan OR bitwise (|). Contoh: tombol yang saat ini dipilih — Button | Selected. VoiceOver akan mengatakan: “Dipilih. Difilter berdasarkan harga. Tombol”.

Mengatur trait dalam kode:

swift
filterButton.accessibilityTraits.insert(.button)
filterButton.accessibilityTraits.insert(.selected)

// Atau melalui mask:
filterButton.accessibilityTraits = [.button, .selected]

Untuk UIView khusus di mana trait tidak diatur secara default:

swift
class CustomToggle: UIControl {
    override var accessibilityTraits: UIAccessibilityTraits {
        get {
            if isOn {
                return [.button, .selected]
            } else {
                return .button
            }
        }
        set {}
    }
}

Aturan penggabungan: tidak lebih dari 3-4 trait per elemen. Trait yang berlebihan (misalnya Button + Link + Header) membuat pengumuman VoiceOver terlalu panjang dan membingungkan. Menurut Apple, “setiap properti tambahan meningkatkan beban kognitif pengguna”.

SwiftUI: pengubah trait

Di SwiftUI trait diatur melalui pengubah .accessibilityAddTraits() dan .accessibilityRemoveTraits(). Contoh: Text(“Judul”).font(.largeTitle).accessibilityAddTraits(.isHeader). Pengubah .isHeader menambahkan UIAccessibilityTraitHeader. Daftar trait SwiftUI: .isButton, .isHeader, .isLink, .isSelected, .isImage, .isSearchField, .isKeyboardKey, .isStaticText, .isSummaryElement, .isToggle, .playsSound, .startsMediaSession, .updatesFrequently, .allowsDirectInteraction, .causesPageTurn, .isModal, .tabBar.

Kesalahan umum saat memilih trait

StaticText bukan Button — kontrol khusus yang secara visual terlihat seperti tombol mendapatkan trait StaticText secara default. VoiceOver tidak menawarkan gerakan aktivasi, pengguna tidak dapat “menekan” elemen. Solusi: atur .button secara eksplisit.

Image tanpa trait — UIImageView dengan accessibility diaktifkan mendapatkan trait Image, meskipun sebenarnya itu adalah tombol untuk memperbesar foto. Tetapkan .button dan Label “Perbesar foto”. Menurut WWDC 2023, “Deliver an Exceptional Accessibility Experience”, 40% regresi accessibility di versi baru aplikasi disebabkan tepat oleh ketidakcocokan trait.

Header pada setiap elemen — trait Header ditujukan untuk header struktural layar. Jika Anda menjadikan setiap UILabel sebagai header, rotor VoiceOver dalam mode “Header” akan menjadi tidak berguna — akan berhenti di setiap kata.

Cara memperbaiki: daftar periksa

  • Setiap elemen khusus interaktif mendapatkan trait Button, Link atau Adjustable
  • Header bagian mendapatkan trait Header (bukan StaticText)
  • Gambar-tombol mendapatkan trait Button + Selected dalam status selected
  • Elemen tanpa gerakan — StaticText atau Image (hanya baca)

Bug regresi saat mengubah UIButton ke UIControl

Penyebab umum hilangnya trait — refactoring: pengembang mengganti UIButton dengan UIControl untuk tampilan khusus. UIButton secara otomatis mendapatkan trait Button, UIControl — tidak. Setelah refactoring perlu mengatur accessibilityTraits = .button secara eksplisit. Tambahkan pemeriksaan ke code review: “Jika Anda mengganti UIButton dengan UIControl — periksa trait”.

Trait dan status dinamis

Untuk elemen dengan status yang berubah (misalnya tombol suka) trait harus berubah secara dinamis. Dalam status “tidak disukai” — Button, dalam status “disukai” — Button + Selected + Image (jika ada ikon). VoiceOver mengubah pengumuman: “Suka. Tombol” vs “Dipilih. Suka. Tombol”. Gunakan accessibilityValue untuk menyampaikan status jika trait Selected tidak mencukupi. Berlaku untuk tombol langganan, favorit, filter dan sakelar.

Analog Android: role dan className

Di Android tidak ada analog langsung untuk trait. Sebagai pengganti mask bit digunakan:

  • className — nilai AccessibilityNodeInfo.className (android.widget.Button, android.widget.TextView)
  • role — atribut dalam XML (peran ditentukan oleh tipe View)
  • stateDescription — analog Selected: menambahkan deskripsi status (aktif/nonaktif)

Untuk View khusus di Android perlu menimpa onInitializeAccessibilityNodeInfo:

kotlin
class CustomButton @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : View(context, attrs) {

    override fun onInitializeAccessibilityNodeInfo(
        info: AccessibilityNodeInfo
    ) {
        super.onInitializeAccessibilityNodeInfo(info)
        info.className = "android.widget.Button"
        info.isClickable = true
    }
}

Pengembang Flutter harus menggunakan parameter semanticsRole di widget Semantics: button, header, image, link, textField dan lainnya. Selain itu tersedia semanticsLabel dan semanticsHint — analog lengkap dari triad iOS Label + Hint + Trait.

Analog web: peran WAI-ARIA

Untuk versi web aplikasi mobile (PWA, WebView) digunakan atribut role dari WAI-ARIA: role="button", role="heading", role="link". Ini adalah analog langsung dari accessibilityTraits. Di aplikasi hibrid periksa apakah WebView meneruskan peran ARIA ke lapisan accessibility native. Untuk ini gunakan protokol UIAccessibilityContainerDataTable di iOS atau setAccessibilityDelegate di Android. WebView dengan JavaScript aktif mungkin tidak meneruskan peran ARIA dengan benar — uji secara terpisah.

AccessibilityNodeInfo: tindakan tambahan

Di Android dapat menambahkan tindakan khusus ke AccessibilityNodeInfo: AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK dan ACTION_LONG_CLICK. Ini adalah analog trait Button dengan gerakan tambahan. Untuk penggeser gunakan ACTION_SET_PROGRESS — analog Adjustable. Untuk Spinner dan DatePicker — ACTION_SET_SELECTION, ACTION_SET_DATE dan ACTION_SET_TIME.

Memeriksa dan menguji trait

Xcode Accessibility Inspector — alat utama untuk iOS: pilih elemen dan lihat bidang Traits. Ini akan menampilkan daftar trait yang diatur. Rotor VoiceOver dalam mode “Elemen” memungkinkan melewati semua kontrol layar.

Tes otomatis di Swift untuk memeriksa trait:

swift
func testSubmitButtonTrait() {
    let app = XCUIApplication()
    app.launch()
    let submitButton = app.buttons["Kirim"]
    XCTAssertTrue(submitButton.isEnabled)
    // XCUIElement tidak menyediakan akses langsung ke trait
    // Pemeriksaan melalui aktivasi gerakan
    submitButton.tap()
    XCTAssertTrue(app.staticTexts["Formulir terkirim"].exists)
}

Pemeriksaan manual melalui VoiceOver: aktifkan VoiceOver, gerakkan jari ke elemen, sentuh dua kali — elemen harus aktif jika itu Button. Jika elemen tidak bereaksi terhadap sentuhan ganda, trait salah. Gunakan gerakan Rotor untuk beralih antar mode (“Header”, “Tautan”, “Tombol”) — setiap mode hanya akan menampilkan elemen dengan trait yang sesuai.

Pengujian unit trait di iOS

Sebelum iOS 14, pengujian unit tidak memiliki akses langsung ke accessibilityTraits. Mulai iOS 14, properti tersedia: XCTAssertEqual(customButton.accessibilityTraits, .button). Gunakan ini dalam pengujian modular untuk memeriksa kontrol khusus. Disarankan untuk menguji setiap UIView khusus baru untuk kebenaran trait, terutama setelah refactoring atau perubahan kelas induk.

Pertanyaan yang Sering Diajukan

Berapa banyak trait yang dapat diatur untuk satu elemen?

Hingga 3-4 trait per elemen. Jumlah yang lebih besar membuat pengumuman VoiceOver berlebihan. Gunakan kombinasi: Button + Selected, Header + StaticText.

Apa trait default UIButton?

UIAccessibilityTraitButton. iOS secara otomatis mengaturnya untuk semua instance UIButton. Jika Anda mewarisi dari UIView dan meniru tombol, trait harus diatur secara manual.

Apakah ada trait “Adjustable” dan untuk apa?

Ya, UIAccessibilityTraitAdjustable — untuk elemen dengan nilai yang dapat disesuaikan (penggeser, pemilih, penghitung). VoiceOver memungkinkan geser ke atas/bawah untuk mengubah nilai dan membaca status saat ini.

Bagaimana cara memeriksa trait di SwiftUI?

Gunakan pengubah .accessibilityAddTraits(): Text(“Judul”).font(.title).accessibilityAddTraits(.isHeader). Metode ini bekerja di iOS 14+.

Apa yang terjadi jika saya tidak mengatur trait untuk kontrol khusus?

VoiceOver akan menetapkan trait None. Elemen tidak akan mendapatkan peran — pembaca layar hanya akan membaca Label tanpa menyebutkan tipenya. Pengguna tidak akan tahu apakah gerakan aktivasi tersedia.

Kesimpulan

  • Accessibility Trait — mask bit UIAccessibilityTraits yang menentukan peran elemen iOS untuk VoiceOver (Button, Header, Link, StaticText dan lainnya)
  • Trait digabungkan melalui OR bitwise ([] di Swift), maksimal 3-4 per elemen
  • UIView khusus harus mendapatkan trait eksplisit — secara default bisa None atau Image
  • Di Android peran ditetapkan melalui className di AccessibilityNodeInfo, di Flutter melalui semanticsRole
  • Trait yang salah (StaticText untuk tombol) merusak skenario VoiceOver: tidak ada gerakan aktivasi
  • Periksa trait melalui Accessibility Inspector di Xcode dan rotor VoiceOver
  • Di SwiftUI gunakan .accessibilityAddTraits() untuk pengaturan trait secara deklaratif

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.

Diskusikan proyek

Baca juga