Accessibility Label — шта је то, основе и како користити за iOS и Android

Аутор: IT Sectr Објављено: 2026-05-16 Време читања: 9 мин

Accessibility Label је име елемента интерфејса које VoiceOver (iOS) или TalkBack (Android) изговара при фокусу. У iOS својство се назива accessibilityLabel, у Android — contentDescription за елементе који не садрже текст. Према Apple Developer Documentation, 2024, етикета је основа приступачности: без ње корисник не може да идентификује елемент. Етикета мора бити јединствена у оквиру екрана и одражавати суштину елемента разумљивим језиком.

Главне тачке

  • Accessibility Label — име елемента које чита читач екрана; поставља се преко accessibilityLabel у iOS и contentDescription у Android
  • Label мора да се поклапа са видљивим текстом елемента или да га замени за нетекстуалне компоненте
  • Сваки Label мора бити јединствен у оквиру екрана — дуплиране етикете дезоријентишу корисника
  • Локализација Label-а је обавезна: етикете се преводе на све подржане језике апликације
  • За прилагођене контроле Label се поставља програмски кроз преписивање својства или NSObject протокола

Шта је Accessibility Label

Accessibility Label је текстуално својство које одређује име елемента за асистивне технологије. Када корисник превлачи прстом по екрану са укљученим VoiceOver-ом, читач екрана изговара Label елемента на којем се налази фокус. Без етикете корисник чује само тип елемента: „дугме", „слика" — без назнаке намене.

Према Google I/O 2024, „Accessibility Testing", 35% критичних кршења приступачности у продавничким апликацијама повезано је са недостатком или неисправношћу Label-а. Accessibility Scanner на Android-у открива недостатак етикете као грешку највише озбиљности.

Принципијелно ограничење: Label не сме да садржи тип елемента. VoiceOver и TalkBack аутоматски додају улогу (button, header, link) у објаву. Ако Label садржи „Дугме за слање", корисник ће чути: „Дугме за слање, дугме" — дуплирање.

Label и WCAG 4.1.2: Name, Role, Value

WCAG 4.1.2 (ниво А) захтева да сваки елемент корисничког интерфејса има програмски одредиво име (name), улогу (role) и вредност (value). Accessibility Label обезбеђује име. Ако Label недостаје, критеријум се сматра прекршеним и апликација не пролази основну сертификацију.

iOS: својство accessibilityLabel

У iOS-у, accessibilityLabel наслеђују сви UIView објекти из протокола UIAccessibility. Ако елемент садржи текст (UIButton са title, UILabel са text), Label се аутоматски поставља једнак том тексту. За UIImageView, прилагођене контроле и контејнере, Label треба поставити ручно.

Пример за прилагођену ћелију табеле:

swift
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:

swift
class RatingView: UIView {
    var rating: Int = 5

    override var accessibilityLabel: String? {
        get { return "Оцена: \(rating) од 5" }
        set {}
    }
}

Apple HIG, 2024 саветује: ако се елемент састоји од више пот-елемената (нпр. картица производа са називом и ценом), спојите их у један приступачни елемент са композитним Label-ом. Поставите isAccessibilityElement = true на родитељу и false на деци.

NSAttributedString и accessibilityLabel

Ако UILabel користи NSAttributedString, accessibilityLabel је подразумевано једнак .string (обичан текст). Ако треба да пренесете семантички другачију вредност (нпр. икона-симбол се чита као „Звезда" уместо симбола ★), експлицитно поставите accessibilityLabel. VoiceOver не чита Unicode симболе смислено.

Android: Label кроз contentDescription

У Android-у, contentDescription обавља функцију Label-а за ImageView, ImageButton и прилагођене View-ове. За TextView и Button са уграђеним текстом није потребно постављати contentDescription — TalkBack чита текст аутоматски.

Програмско постављање кроз Kotlin:

kotlin
binding.iconStar.contentDescription = "Производ у омиљенима"

// За прилагођени приказ са више елемената
binding.customCard.setContentDescription(
    "\(title) у износу од \(price)")

У XML-у за декоративне елементе:

xml
<ImageView
    android:contentDescription="@null"
    android:src="@drawable/divider"
    android:importantForAccessibility="no" />

Својство importantForAccessibility = "no" потпуно искључује елемент из стабла приступачности. У iOS-у аналог је isAccessibilityElement = false.

Compose: semantics и contentDescription

У Jetpack Compose-у Label се поставља кроз модификатор semantics:

kotlin
Image(
    painter = painterResource(R.drawable.ic_search),
    contentDescription = "Претрага производа",
    modifier = Modifier.semantics {
        contentDescription = "Претрага производа"
    }
)

У Compose-у, contentDescription је обавезан параметар за Image — без њега код се не компајлира (упозорење). Ово принудно побољшава приступачност кроз дизајн API-ја.

Label и Hint: разлика улога

Accessibility Label одговара на питање „Који је ово елемент?". Hint (accessibilityHint у iOS-у, додатни текст у contentDescription у Android-у) — „Шта ће се десити при интеракцији?". VoiceOver их изговара секвенцијално: прво Label, затим Hint.

Пример за дугме за брисање:

  • Label: „Обриши"
  • Hint: „Неповратно ће обрисати изабрану фотографију"
  • VoiceOver: „Обриши. Неповратно ће обрисати изабрану фотографију"

Према Deque University, 2024, правилно раздвајање Label-а и Hint-а повећава стопу успешности извршавања задатака за кориснике VoiceOver-а за 28%. Корисници са когнитивним потешкоћама су посебно зависни од Hint-а: ризикујући да притисну „Обриши" без објашњења, 40% одустаје од радње.

Када Hint није потребан

  • Елемент са интуитивно разумљивом радњом („Назад", „Затвори" — Label је довољан)
  • Label већ описује резултат („Пошаљи поруку" — глагол у самом имену)
  • Системске контроле (UISwitch, UIButton са системским типом) — њихово понашање је стандардно

Грешке из праксе: Label уместо Hint-а

Честа грешка: у Label-у пишу „Дугме за брисање" уместо „Обриши". Тип елемента (дугме) се додаје аутоматски кроз VoiceOver trait. Као резултат, корисник чује: „Дугме за брисање, дугме" — дуплирање. Исправан Label: „Обриши", Hint: „Обрисаће изабрану фотографију".

Локализација и најбоље праксе

Локализација етикета је обавезна — иде кроз стандардне механизме: NSLocalizedString у iOS-у, ресурси ниски @string/ у Android-у. Никада не постављајте Label конкатенацијом на енглеском без локализације.

Правила доброг Label-а, заснована на W3C WCAG 2.2:

  • Почините кључном речи — „Претрага производа", а не „Поље за претрагу производа"
  • Немојте укључивати реч „дугме", „поље", „слика" — улога се додаје аутоматски
  • Користите природан језик, разумљив циљној публици
  • Избегавајте скраћенице (осим општеприхваћених: „ком.", „кг.") — читач екрана их чита дословно
  • За елементе уноса додајте пример: „Email (example@domain.com)"

Доследност Label-а у оквиру бренда

Користите јединствени глосар за Label у апликацији. Ако на једном екрану пише „Омиљено", а на другом „Маркери", корисник је дезоријентисан. Направите табелу термина приступачности — усагласите са дизајнерима и локализаторима.

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:

swift
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:

kotlin
@Test
fun testButtonHasAccessibilityLabel() {
    onView(withId(R.id.btnSubmit))
        .check(matches(
            withContentDescription(containsString("Пошаљи"))
        ))
}

Ручно тестирање: укључите VoiceOver (iOS) или TalkBack (Android) и превуците прстом удесно кроз све елементе екрана. Сваки елемент треба да добије смислену објаву. Ако чујете само „дугме" или „слика" — Label недостаје.

VoiceOver-ротор и брза навигација

Након подешавања Label-а, корисник VoiceOver-а може да користи ротор за брзу навигацију: режими „Дугмад", „Наслови", „Линкови" и други. Ако је Label исправно постављен, VoiceOver укључује елемент у одговарајући режим ротора. Проверите да су сва дугмад видљива у режиму „Дугмад", а сви наслови у „Наслови".

Label такође утиче на претрагу VoiceOver-а. Корисник може да унесе реч у режиму претраге, а VoiceOver ће померити фокус на елемент са одговарајућим Label-ом. Због тога Label треба да садржи кључне речи по којима ће корисник тражити елемент.

Интеграција у CI/CD пајплајн

Додајте проверу Label-а у пајплајн. На iOS-у користите XCUITest са fastlane scan. На Android-у — Accessibility Test Framework са правилом AccessibilityCheckRule које детектује празне contentDescription. Ово спречава регресије при спајању нових екрана.

Често постављана питања

Чим се Accessibility Label разликује од Accessibility Hint-а?

Label идентификује елемент („Претрага"), Hint објашњава резултат радње („Отвориће екран претраге"). VoiceOver изговара Label одмах при фокусу, а Hint у режиму детаљних описа.

Да ли је потребно поставити Label за UILabel са текстом?

У iOS-у UILabel аутоматски добија accessibilityLabel једнак свом тексту. Додатно постављање није потребно. У Android-у TextView се понаша слично.

Како поставити Label за прилагођени UIView?

Поставите isAccessibilityElement = true на родитељском прегледу и препишите accessibilityLabel, враћајући конкатенирани текст из подређених елемената. За сложене компоненте користите спајање са сепаратором.

Како избећи дуплирање Label-а на екрану?

Додајте контекст елементима који се понављају: „Купи iPhone 15", „Купи iPhone 15 Pro". Аутоматизујте проверу кроз UI тестове — прикупите све Label-ове и проверите одсуство дупликата.

Може ли се Label користити за скривање елемента од читача екрана?

Не. За скривање елемента користите isAccessibilityElement = false у iOS-у или importantForAccessibility = "no" у Android-у. Празан Label не скрива елемент — читач екрана ће прочитати „без назива".

Резиме

  • Accessibility Label — име елемента за VoiceOver и TalkBack; поставља се кроз accessibilityLabel у iOS-у и contentDescription у Android-у
  • Label мора да се поклапа са видљивим текстом текстуалних елемената; за нетекстуалне (иконе, слике) поставља се ручно
  • Hint одговара на питање „Шта ће се десити?" и не дуплира Label — ова својства имају различите улоге
  • Сваки Label мора бити јединствен на екрану; дуплирање дезоријентише корисника читача екрана
  • Локализација етикета је обавезна кроз NSLocalizedString (iOS) и @string (Android)
  • Тестирајте Label аутоматски кроз UI тестове (XCUIApplication, AccessibilityCheckRule) и ручно кроз VoiceOver
  • Декоративне елементе сакријте кроз isAccessibilityElement = false или importantForAccessibility = "no"

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође