Accessibility Label este numele elementului de interfață pe care VoiceOver (iOS) sau TalkBack (Android) îl pronunță la focalizare. În iOS proprietatea se numește accessibilityLabel, iar în Android — contentDescription pentru elementele care nu conțin text. Conform Apple Developer Documentation, 2024, eticheta este baza accesibilității: fără ea, utilizatorul nu poate identifica elementul. Eticheta trebuie să fie unică în cadrul ecranului și să reflecte esența elementului într-un limbaj ușor de înțeles.
Principalele puncte
Accessibility Label este o proprietate șir care definește numele elementului pentru tehnologiile de asistare. Când utilizatorul glisează degetul pe ecran cu VoiceOver activat, cititorul de ecran citește Labelul elementului pe care se află focalizarea. Fără etichetă, utilizatorul aude doar tipul elementului: „buton”, „imagine” — fără a indica destinația.
Conform Google I/O 2024, „Accessibility Testing”, 35% din încălcările critice de accesibilitate în aplicațiile din magazine sunt legate de absența sau incorectitudinea Label. Accessibility Scanner pe Android detectează lipsa etichetei ca o eroare de cea mai mare severitate.
Limitarea principală: Label nu trebuie să conțină tipul elementului. VoiceOver și TalkBack adaugă automat rolul (button, header, link) în anunț. Dacă Label conține „Buton de trimitere”, utilizatorul va auzi: „Buton de trimitere, buton” — duplicare.
WCAG 4.1.2 (nivelul A) cere ca fiecare element al interfeței de utilizator să aibă un nume (name), rol (role) și valoare (value) determinabile programatic. Accessibility Label asigură numele. Dacă Label lipsește, criteriul este considerat încălcat și aplicația nu trece de certificarea de bază.
În iOS, accessibilityLabel este moștenit de toate UIView din protocolul UIAccessibility. Dacă elementul conține text (UIButton cu title, UILabel cu text), Label se setează automat egal cu acest text. Pentru UIImageView, controale personalizate și containere, Label trebuie setat manual.
Exemplu pentru o celulă personalizată de tabel:
class CustomTableViewCell: UITableViewCell {
let titleLabel = UILabel()
let priceLabel = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
self.isAccessibilityElement = true
self.accessibilityLabel =
"\(titleLabel.text ?? "") - \(priceLabel.text ?? "")"
}
}
Pentru UIView personalizate se poate suprascrie getter-ul accessibilityLabel:
class RatingView: UIView {
var rating: Int = 5
override var accessibilityLabel: String? {
get { return "Evaluare: \(rating) din 5" }
set {}
}
}
Apple HIG, 2024 recomandă: dacă elementul constă din mai multe subelemente (de exemplu, o carte de produs cu nume și preț), combinați-le într-un singur element de accesibilitate cu un Label compozit. Setați isAccessibilityElement = true pe părinte și false pe copii.
Dacă UILabel utilizează NSAttributedString, accessibilityLabel este implicit egal cu .string (text simplu). Dacă trebuie să transmiteți o valoare semantic diferită (de exemplu, o iconiță-simbol citită ca „Stea” în loc de simbolul ★), setați explicit accessibilityLabel. VoiceOver nu citește simbolurile Unicode într-un mod inteligibil.
În Android, contentDescription îndeplinește funcția de Label pentru ImageView, ImageButton și View-uri personalizate. Pentru TextView și Button cu text încorporat, nu este necesar să setați contentDescription — TalkBack citește textul automat.
Setarea programatică prin Kotlin:
binding.iconStar.contentDescription = "Produs în favorite"
// Pentru vizualizare personalizată cu mai multe elemente
binding.customCard.setContentDescription(
"\(title) în valoare de \(price)")
În XML pentru elemente decorative:
<ImageView
android:contentDescription="@null"
android:src="@drawable/divider"
android:importantForAccessibility="no" />
Proprietatea importantForAccessibility = "no" exclude complet elementul din arborele de accesibilitate. În iOS, analogul este isAccessibilityElement = false.
În Jetpack Compose, Label se setează prin modificatorul semantics:
Image(
painter = painterResource(R.drawable.ic_search),
contentDescription = "Căutare produse",
modifier = Modifier.semantics {
contentDescription = "Căutare produse"
}
)
În Compose, contentDescription este un parametru obligatoriu pentru Image — fără el, codul nu se compilează (avertisment). Aceasta îmbunătățește forțat accesibilitatea prin designul API-ului.
Accessibility Label răspunde la întrebarea „Ce element este acesta?”. Hint (accessibilityHint în iOS, text suplimentar în contentDescription în Android) — „Ce se va întâmpla la interacțiune?”. VoiceOver le pronunță secvențial: mai întâi Label, apoi Hint.
Exemplu pentru butonul de ștergere:
Conform Deque University, 2024, separarea corectă a Label și Hint crește rata de reușită a sarcinilor pentru utilizatorii VoiceOver cu 28%. Utilizatorii cu deficiențe cognitive sunt deosebit de dependenți de Hint: riscând să apese „Ștergeți” fără explicație, 40% renunță la acțiune.
O eroare frecventă: în Label scriu „Buton de ștergere” în loc de „Ștergeți”. Tipul elementului (buton) este adăugat automat de VoiceOver prin trait. Ca urmare, utilizatorul aude: „Buton de ștergere, buton” — duplicare. Label corect: „Ștergeți”, Hint: „Va șterge fotografia selectată”.
Localizarea etichetelor este obligatorie — se realizează prin mecanisme standard: NSLocalizedString în iOS, resurse șir @string/ în Android. Nu setați niciodată Label prin concatenare în engleză fără localizare.
Regulile unui Label bun, bazate pe W3C WCAG 2.2:
Folosiți un glosar unitar pentru Label în aplicație. Dacă pe un ecran scrie „Favorite”, iar pe altul „Semnite de carte”, utilizatorul este dezorientat. Creați un tabel de termeni de accesibilitate — coordonați-vă cu designeri și localizatori.
Pentru câmpuri de introducere (UITextField, EditText), Label trebuie să coincidă cu placeholderul sau titlul câmpului. Însă placeholderul dispare adesea după introducerea textului. Folosiți accessibilityLabel pentru numele permanent și accessibilityValue pentru conținutul curent al câmpului — acesta este standardul WCAG 4.1.2. Soluția: setați accessibilityLabel static (egal cu titlul câmpului), iar accessibilityValue dinamic (egal cu textul introdus). În iOS, acest lucru este automat, dar pentru câmpuri personalizate — manual prin suprascrierea accessibilityValue. Verificați ca VoiceOver să citească: „Email, example@domain.com, câmp text” în loc de „, câmp text”.
Testarea automatizată este singura modalitate de a garanta corectitudinea Label pe toate ecranele. iOS oferă XCUIApplication cu acces la .label, Android — AccessibilityCheckRule și setContentDescription.
Exemplu de test pentru iOS:
func testLabelsAreUnique() {
let app = XCUIApplication()
app.launch()
let allButtons = app.buttons.allElementsBoundByIndex
let labels = allButtons.compactMap { $0.label }
let uniqueLabels = Set(labels)
XCTAssertEqual(labels.count, uniqueLabels.count,
"S-au găsit etichete duplicate")
}
Exemplu pentru Android cu Espresso:
@Test
fun testButtonHasAccessibilityLabel() {
onView(withId(R.id.btnSubmit))
.check(matches(
withContentDescription(containsString("Trimiteți"))
))
}
Testare manuală: activați VoiceOver (iOS) sau TalkBack (Android) și glisați cu degetul la dreapta prin toate elementele ecranului. Fiecare element trebuie să primească un anunț semnificativ. Dacă auziți doar „buton” sau „imagine” — Label lipsește.
După configurarea Label, utilizatorul VoiceOver poate folosi rotorul pentru navigare rapidă: modurile „Butoane”, „Antete”, „Linkuri” și altele. Dacă Label este setat corect, VoiceOver include elementul în modul rotor corespunzător. Verificați ca toate butoanele să fie vizibile în modul „Butoane”, iar toate antetele în „Antete”.
Label influențează, de asemenea, căutarea VoiceOver. Utilizatorul poate introduce un cuvânt în modul de căutare, iar VoiceOver va muta focalizarea pe elementul cu Labelul potrivit. De aceea, Label trebuie să conțină cuvintele cheie după care utilizatorul va căuta elementul.
Adăugați verificarea Label în pipeline. Pe iOS, utilizați XCUITest cu fastlane scan. Pe Android — Accessibility Test Framework cu regula AccessibilityCheckRule care detectează contentDescription-urile goale. Aceasta previne regresiile la îmbinarea noilor ecrane.
Întrebări frecvente
Label identifică elementul („Căutare”), Hint explică rezultatul acțiunii („Va deschide ecranul de căutare”). VoiceOver pronunță Label imediat la focalizare, iar Hint în modul descrieri detaliate.
În iOS, UILabel primește automat accessibilityLabel egal cu textul său. Nu este necesară setarea suplimentară. În Android, TextView se comportă similar.
Setați isAccessibilityElement = true pe View-ul părinte și suprascrieți accessibilityLabel, returnând textul concatenat din elementele copil. Pentru componente complexe, utilizați concatenarea cu separator.
Adăugați context elementelor care se repetă: „Cumpărați iPhone 15”, „Cumpărați iPhone 15 Pro”. Automatizați verificarea prin teste UI — colectați toate Label-urile și verificați absența duplicatelor.
Nu. Pentru a ascunde un element, utilizați isAccessibilityElement = false în iOS sau importantForAccessibility = "no" în Android. Un Label gol nu ascunde elementul — cititorul de ecran va citi „fără nume”.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și