Accessibility Label је име елемента интерфејса које VoiceOver (iOS) или TalkBack (Android) изговара при фокусу. У iOS својство се назива accessibilityLabel, у Android — contentDescription за елементе који не садрже текст. Према Apple Developer Documentation, 2024, етикета је основа приступачности: без ње корисник не може да идентификује елемент. Етикета мора бити јединствена у оквиру екрана и одражавати суштину елемента разумљивим језиком.
Главне тачке
Accessibility Label је текстуално својство које одређује име елемента за асистивне технологије. Када корисник превлачи прстом по екрану са укљученим VoiceOver-ом, читач екрана изговара Label елемента на којем се налази фокус. Без етикете корисник чује само тип елемента: „дугме", „слика" — без назнаке намене.
Према Google I/O 2024, „Accessibility Testing", 35% критичних кршења приступачности у продавничким апликацијама повезано је са недостатком или неисправношћу Label-а. Accessibility Scanner на Android-у открива недостатак етикете као грешку највише озбиљности.
Принципијелно ограничење: Label не сме да садржи тип елемента. VoiceOver и TalkBack аутоматски додају улогу (button, header, link) у објаву. Ако Label садржи „Дугме за слање", корисник ће чути: „Дугме за слање, дугме" — дуплирање.
WCAG 4.1.2 (ниво А) захтева да сваки елемент корисничког интерфејса има програмски одредиво име (name), улогу (role) и вредност (value). Accessibility Label обезбеђује име. Ако Label недостаје, критеријум се сматра прекршеним и апликација не пролази основну сертификацију.
У iOS-у, accessibilityLabel наслеђују сви UIView објекти из протокола UIAccessibility. Ако елемент садржи текст (UIButton са title, UILabel са text), Label се аутоматски поставља једнак том тексту. За UIImageView, прилагођене контроле и контејнере, Label треба поставити ручно.
Пример за прилагођену ћелију табеле:
class CustomTableViewCell: UITableViewCell {
let titleLabel = UILabel()
let priceLabel = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
self.isAccessibilityElement = true
self.accessibilityLabel =
"\(titleLabel.text ?? "") - \(priceLabel.text ?? "")"
}
}
За прилагођене UIView могуће је преписивати гетер accessibilityLabel:
class RatingView: UIView {
var rating: Int = 5
override var accessibilityLabel: String? {
get { return "Оцена: \(rating) од 5" }
set {}
}
}
Apple HIG, 2024 саветује: ако се елемент састоји од више пот-елемената (нпр. картица производа са називом и ценом), спојите их у један приступачни елемент са композитним Label-ом. Поставите isAccessibilityElement = true на родитељу и false на деци.
Ако UILabel користи NSAttributedString, accessibilityLabel је подразумевано једнак .string (обичан текст). Ако треба да пренесете семантички другачију вредност (нпр. икона-симбол се чита као „Звезда" уместо симбола ★), експлицитно поставите accessibilityLabel. VoiceOver не чита Unicode симболе смислено.
У Android-у, contentDescription обавља функцију Label-а за ImageView, ImageButton и прилагођене View-ове. За TextView и Button са уграђеним текстом није потребно постављати contentDescription — TalkBack чита текст аутоматски.
Програмско постављање кроз Kotlin:
binding.iconStar.contentDescription = "Производ у омиљенима"
// За прилагођени приказ са више елемената
binding.customCard.setContentDescription(
"\(title) у износу од \(price)")
У XML-у за декоративне елементе:
<ImageView
android:contentDescription="@null"
android:src="@drawable/divider"
android:importantForAccessibility="no" />
Својство importantForAccessibility = "no" потпуно искључује елемент из стабла приступачности. У iOS-у аналог је isAccessibilityElement = false.
У Jetpack Compose-у Label се поставља кроз модификатор semantics:
Image(
painter = painterResource(R.drawable.ic_search),
contentDescription = "Претрага производа",
modifier = Modifier.semantics {
contentDescription = "Претрага производа"
}
)
У Compose-у, contentDescription је обавезан параметар за Image — без њега код се не компајлира (упозорење). Ово принудно побољшава приступачност кроз дизајн API-ја.
Accessibility Label одговара на питање „Који је ово елемент?". Hint (accessibilityHint у iOS-у, додатни текст у contentDescription у Android-у) — „Шта ће се десити при интеракцији?". VoiceOver их изговара секвенцијално: прво Label, затим Hint.
Пример за дугме за брисање:
Према Deque University, 2024, правилно раздвајање Label-а и Hint-а повећава стопу успешности извршавања задатака за кориснике VoiceOver-а за 28%. Корисници са когнитивним потешкоћама су посебно зависни од Hint-а: ризикујући да притисну „Обриши" без објашњења, 40% одустаје од радње.
Честа грешка: у Label-у пишу „Дугме за брисање" уместо „Обриши". Тип елемента (дугме) се додаје аутоматски кроз VoiceOver trait. Као резултат, корисник чује: „Дугме за брисање, дугме" — дуплирање. Исправан Label: „Обриши", Hint: „Обрисаће изабрану фотографију".
Локализација етикета је обавезна — иде кроз стандардне механизме: NSLocalizedString у iOS-у, ресурси ниски @string/ у Android-у. Никада не постављајте Label конкатенацијом на енглеском без локализације.
Правила доброг Label-а, заснована на W3C WCAG 2.2:
Користите јединствени глосар за Label у апликацији. Ако на једном екрану пише „Омиљено", а на другом „Маркери", корисник је дезоријентисан. Направите табелу термина приступачности — усагласите са дизајнерима и локализаторима.
За поља за унос (UITextField, EditText) Label мора да се поклапа са placeholder-ом или насловом поља. Међутим, placeholder често нестаје након уноса текста. Користите accessibilityLabel за стално име и accessibilityValue за тренутни садржај поља — ово је стандард WCAG 4.1.2. Решење: поставите accessibilityLabel статички (једнак наслову поља), а accessibilityValue динамички (једнак унетом тексту). У iOS-у је ово аутоматско, али за прилагођена поља — ручно кроз преписивање accessibilityValue. Проверите да VoiceOver чита: „Email, example@domain.com, текстуално поље" уместо „, текстуално поље".
Аутоматизовано тестирање је једини начин да се гарантује исправност Label-а на свим екранима. iOS пружа XCUIApplication са приступом .label-у, Android — AccessibilityCheckRule и setContentDescription.
Пример теста за 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,
"Пронађене дуплиране Label-ове")
}
Пример за Android са Espresso:
@Test
fun testButtonHasAccessibilityLabel() {
onView(withId(R.id.btnSubmit))
.check(matches(
withContentDescription(containsString("Пошаљи"))
))
}
Ручно тестирање: укључите VoiceOver (iOS) или TalkBack (Android) и превуците прстом удесно кроз све елементе екрана. Сваки елемент треба да добије смислену објаву. Ако чујете само „дугме" или „слика" — Label недостаје.
Након подешавања Label-а, корисник VoiceOver-а може да користи ротор за брзу навигацију: режими „Дугмад", „Наслови", „Линкови" и други. Ако је Label исправно постављен, VoiceOver укључује елемент у одговарајући режим ротора. Проверите да су сва дугмад видљива у режиму „Дугмад", а сви наслови у „Наслови".
Label такође утиче на претрагу VoiceOver-а. Корисник може да унесе реч у режиму претраге, а VoiceOver ће померити фокус на елемент са одговарајућим Label-ом. Због тога Label треба да садржи кључне речи по којима ће корисник тражити елемент.
Додајте проверу Label-а у пајплајн. На iOS-у користите XCUITest са fastlane scan. На Android-у — Accessibility Test Framework са правилом AccessibilityCheckRule које детектује празне contentDescription. Ово спречава регресије при спајању нових екрана.
Често постављана питања
Label идентификује елемент („Претрага"), Hint објашњава резултат радње („Отвориће екран претраге"). VoiceOver изговара Label одмах при фокусу, а Hint у режиму детаљних описа.
У iOS-у UILabel аутоматски добија accessibilityLabel једнак свом тексту. Додатно постављање није потребно. У Android-у TextView се понаша слично.
Поставите isAccessibilityElement = true на родитељском прегледу и препишите accessibilityLabel, враћајући конкатенирани текст из подређених елемената. За сложене компоненте користите спајање са сепаратором.
Додајте контекст елементима који се понављају: „Купи iPhone 15", „Купи iPhone 15 Pro". Аутоматизујте проверу кроз UI тестове — прикупите све Label-ове и проверите одсуство дупликата.
Не. За скривање елемента користите isAccessibilityElement = false у iOS-у или importantForAccessibility = "no" у Android-у. Празан Label не скрива елемент — читач екрана ће прочитати „без назива".
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође