Accessibility Label — co to jest, podstawy i jak używać dla iOS i Android

Autor: IT Sectr Opublikowano: 2026-05-16 Czas czytania: 9 min

Accessibility Label to nazwa elementu interfejsu, którą VoiceOver (iOS) lub TalkBack (Android) wypowiada po ustawieniu fokusu. W iOS właściwość nazywa się accessibilityLabel, w Android — contentDescription dla elementów niezawierających tekstu. Według Apple Developer Documentation, 2024, etykieta to podstawa dostępności: bez niej użytkownik nie może zidentyfikować elementu. Etykieta powinna być unikalna w obrębie ekranu i odzwierciedlać istotę elementu zrozumiałym językiem.

Najważniejsze

  • Accessibility Label — nazwa elementu odczytywana przez czytnik ekranu; ustawiana przez accessibilityLabel w iOS i contentDescription w Android
  • Label powinien być zgodny z widocznym tekstem elementu lub go zastępować dla komponentów nietekstowych
  • Każdy Label musi być unikalny w obrębie ekranu — duplikujące się etykiety dezorientują użytkownika
  • Lokalizacja Label jest obowiązkowa: etykiety tłumaczy się na wszystkie obsługiwane języki aplikacji
  • Dla niestandardowych kontrolek Label ustawia się programowo poprzez nadpisanie właściwości lub protokołu NSObject

Co to jest Accessibility Label

Accessibility Label to właściwość tekstowa określająca nazwę elementu dla technologii asystujących. Gdy użytkownik przesuwa palcem po ekranie z włączonym VoiceOver, czytnik ekranu odczytuje Label elementu, na którym znajduje się fokus. Bez etykiety użytkownik słyszy tylko typ elementu: „przycisk”, „obraz” — bez określenia przeznaczenia.

Według Google I/O 2024, „Accessibility Testing”, 35% krytycznych naruszeń dostępności w aplikacjach sklepowych jest związanych z brakiem lub nieprawidłowym Label. Accessibility Scanner na Android wykrywa brak etykiety jako błąd najwyższej wagi.

Zasadnicze ograniczenie: Label nie powinien zawierać typu elementu. VoiceOver i TalkBack automatycznie dodają rolę (button, header, link) w komunikacie. Jeśli Label zawiera „Przycisk wysyłania”, użytkownik usłyszy: „Przycisk wysyłania, przycisk” — powielenie.

Label i WCAG 4.1.2: Name, Role, Value

WCAG 4.1.2 (poziom A) wymaga, aby każdy element interfejsu użytkownika miał programowo określoną nazwę (name), rolę (role) i wartość (value). Accessibility Label zapewnia name. Jeśli Label brakuje, kryterium jest uznawane za naruszone, a aplikacja nie przechodzi podstawowej certyfikacji.

iOS: właściwość accessibilityLabel

W iOS accessibilityLabel jest dziedziczony przez wszystkie UIView z protokołu UIAccessibility. Jeśli element zawiera tekst (UIButton z title, UILabel z text), Label jest automatycznie ustawiany na ten tekst. Dla UIImageView, niestandardowych kontrolek i kontenerów Label trzeba ustawić ręcznie.

Przykład dla niestandardowej komórki tabeli:

swift
class CustomTableViewCell: UITableViewCell {
    let titleLabel = UILabel()
    let priceLabel = UILabel()

    override func awakeFromNib() {
        super.awakeFromNib()
        self.isAccessibilityElement = true
        self.accessibilityLabel =
            "\(titleLabel.text ?? "") - \(priceLabel.text ?? "")"
    }
}

Dla niestandardowych UIView można nadpisać getter accessibilityLabel:

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

    override var accessibilityLabel: String? {
        get { return "Ocena: \(rating) z 5" }
        set {}
    }
}

Apple HIG, 2024 zaleca: jeśli element składa się z kilku subelementów (np. karta produktu z nazwą i ceną), połącz je w jeden accessibility-element złożoną etykietą. Ustaw isAccessibilityElement = true na rodzicu i false na dzieciach.

NSAttributedString i accessibilityLabel

Jeśli UILabel używa NSAttributedString, accessibilityLabel domyślnie jest równy .string (plain text). Jeśli potrzebujesz przekazać semantycznie inną wartość (np. ikona-symbol czytana jako „Gwiazda” zamiast symbolu ★), jawnie ustaw accessibilityLabel. VoiceOver nie czyta symboli Unicode w sposób zrozumiały.

Android: Label przez contentDescription

W Android contentDescription pełni funkcję Label dla ImageView, ImageButton i niestandardowych View. Dla TextView i Button z wbudowanym tekstem nie trzeba ustawiać contentDescription — TalkBack czyta tekst automatycznie.

Programowe ustawienie przez Kotlin:

kotlin
binding.iconStar.contentDescription = "Produkt w ulubionych"

// Dla niestandardowego widoku z wieloma elementami
binding.customCard.setContentDescription(
    "\(title) za kwotę \(price)")

W XML dla elementów dekoracyjnych:

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

Właściwość importantForAccessibility = "no" całkowicie wyklucza element z drzewa dostępności. W iOS odpowiednik to isAccessibilityElement = false.

Compose: semantics i contentDescription

W Jetpack Compose Label ustawia się przez modyfikator semantics:

kotlin
Image(
    painter = painterResource(R.drawable.ic_search),
    contentDescription = "Wyszukiwanie produktów",
    modifier = Modifier.semantics {
        contentDescription = "Wyszukiwanie produktów"
    }
)

W Compose contentDescription to obowiązkowy parametr dla Image — bez niego kod się nie skompiluje (warning). To wymusza poprawę dostępności poprzez projekt API.

Label i Hint: różnica ról

Accessibility Label odpowiada na pytanie „Co to za element?”. Hint (accessibilityHint w iOS, dodatkowy tekst w contentDescription w Android) — „Co się stanie przy interakcji?”. VoiceOver wypowiada je kolejno: najpierw Label, potem Hint.

Przykład dla przycisku usuwania:

  • Label: „Usuń”
  • Hint: „Nieodwracalnie usunie wybrane zdjęcie”
  • VoiceOver: „Usuń. Nieodwracalnie usunie wybrane zdjęcie”

Według Deque University, 2024, prawidłowe rozdzielenie Label i Hint zwiększa wskaźnik powodzenia wykonywania zadań dla użytkowników VoiceOver o 28%. Użytkownicy z zaburzeniami poznawczymi są szczególnie zależni od Hint: ryzykując naciśnięcie „Usuń” bez wyjaśnienia, 40% rezygnuje z działania.

Kiedy Hint nie jest potrzebny

  • Element z intuicyjnie zrozumiałym działaniem („Wstecz”, „Zamknij” — Label wystarczy)
  • Label już opisuje wynik („Wyślij wiadomość” — czasownik w samej nazwie)
  • Systemowe kontrolki (UISwitch, UIButton z typem systemowym) — ich zachowanie jest standardowe

Błędy z praktyki: Label zamiast Hint

Częsty błąd: w Label piszą „Przycisk usuwania” zamiast „Usuń”. Typ elementu (Button) jest dodawany przez VoiceOver automatycznie poprzez trait. W rezultacie użytkownik słyszy: „Przycisk usuwania, przycisk” — powielenie. Prawidłowy Label: „Usuń”, Hint: „Usunie wybrane zdjęcie”.

Lokalizacja i najlepsze praktyki

Lokalizacja etykiet jest obowiązkowa — odbywa się poprzez standardowe mechanizmy: NSLocalizedString w iOS, zasoby ciągów @string/ w Android. Nigdy nie ustawiaj Label przez konkatenację po angielsku bez lokalizacji.

Zasady dobrego Label, oparte na W3C WCAG 2.2:

  • Zaczynaj od słowa kluczowego — „Wyszukiwanie produktów”, a nie „Pole do wyszukiwania produktów”
  • Nie dołączaj słowa „przycisk”, „pole”, „obraz” — rola jest dodawana automatycznie
  • Używaj naturalnego języka, zrozumiałego dla docelowej grupy odbiorców
  • Unikaj skrótów (poza powszechnie przyjętymi: „szt.”, „kg.”) — czytnik ekranu odczytuje je dosłownie
  • Dla elementów wejścia dodawaj przykład: „Email (example@domain.com)”

Spójność Label w ramach marki

Używaj jednolitego glosariusza dla Label w aplikacji. Jeśli na jednym ekranie jest napisane „Ulubione”, a na drugim „Zakładki”, użytkownik jest zdezorientowany. Stwórz tabelę terminów dostępności — uzgodnij z projektantami i lokalizatorami.

Label dla elementów formularzy

Dla pól wprowadzania (UITextField, EditText) Label powinien być zgodny z placeholderem lub tytułem pola. Jednak placeholder często znika po wprowadzeniu tekstu. Używaj accessibilityLabel dla stałej nazwy i accessibilityValue dla bieżącej zawartości pola — to standard WCAG 4.1.2. Rozwiązanie: ustaw accessibilityLabel statycznie (równy tytułowi pola), a accessibilityValue dynamicznie (równy wprowadzonemu tekstowi). W iOS jest to automatyczne, ale dla niestandardowych pól — ręcznie przez nadpisanie accessibilityValue. Sprawdź, czy VoiceOver czyta: „Email, example@domain.com, pole tekstowe” zamiast „, pole tekstowe”.

Jak testować etykiety dostępności

Zautomatyzowane testowanie to jedyny sposób zagwarantowania poprawności Label na wszystkich ekranach. iOS udostępnia XCUIApplication z dostępem do .label, Android — AccessibilityCheckRule i setContentDescription.

Przykład testu dla 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,
        "Znaleziono duplikujące się Label")
}

Przykład dla Android z Espresso:

kotlin
@Test
fun testButtonHasAccessibilityLabel() {
    onView(withId(R.id.btnSubmit))
        .check(matches(
            withContentDescription(containsString("Wyślij"))
        ))
}

Testowanie ręczne: włącz VoiceOver (iOS) lub TalkBack (Android) i przesuń gestem w prawo po wszystkich elementach ekranu. Każdy element powinien otrzymać sensowny komunikat. Jeśli słyszysz tylko „przycisk” lub „obraz” — Label brakuje.

Rotor VoiceOver i szybka nawigacja

Po skonfigurowaniu Label użytkownik VoiceOver może używać rotora do szybkiej nawigacji: tryby „Przyciski”, „Nagłówki”, „Linki” i inne. Jeśli Label jest poprawnie ustawiony, VoiceOver włącza element do odpowiedniego trybu rotora. Sprawdź, czy wszystkie przyciski są widoczne w trybie „Przyciski”, a wszystkie nagłówki w „Nagłówki”.

Label wpływa również na wyszukiwanie VoiceOver. Użytkownik może wpisać słowo w trybie wyszukiwania, a VoiceOver przeniesie fokus na element z pasującym Labelem. Dlatego w Label powinny znajdować się słowa kluczowe, po których użytkownik będzie szukać elementu.

Integracja z pipeline CI/CD

Dodaj sprawdzanie Label do pipeline. Na iOS używaj XCUITest z fastlane scan. Na Android — Accessibility Test Framework z regułą AccessibilityCheckRule, która wykrywa puste contentDescription. Zapobiega to regresjom przy scalaniu nowych ekranów.

Często zadawane pytania

Czym Accessibility Label różni się od Accessibility Hint?

Label identyfikuje element („Wyszukiwanie”), Hint wyjaśnia rezultat działania („Otworzy ekran wyszukiwania”). VoiceOver wypowiada Label natychmiast po ustawieniu fokusu, a Hint w trybie szczegółowych opisów.

Czy trzeba ustawiać Label dla UILabel z tekstem?

W iOS UILabel automatycznie otrzymuje accessibilityLabel równy swojemu tekstowi. Nie trzeba go dodatkowo ustawiać. W Android TextView zachowuje się analogicznie.

Jak ustawić Label dla niestandardowego UIView?

Ustaw isAccessibilityElement = true na widoku nadrzędnym i nadpisz accessibilityLabel, zwracając skonkatenowany tekst z elementów podrzędnych. Dla złożonych komponentów używaj połączenia z separatorem.

Jak uniknąć powielania Label na ekranie?

Dodawaj kontekst do powtarzających się elementów: „Kup iPhone 15”, „Kup iPhone 15 Pro”. Automatyzuj sprawdzanie przez testy UI — zbieraj wszystkie Label i sprawdzaj brak duplikatów.

Czy można użyć Label do ukrycia elementu przed czytnikiem ekranu?

Nie. Do ukrycia elementu używaj isAccessibilityElement = false w iOS lub importantForAccessibility = "no" w Android. Pusty Label nie ukrywa elementu — czytnik ekranu odczyta „bez nazwy”.

Podsumowanie

  • Accessibility Label — nazwa elementu dla VoiceOver i TalkBack; ustawiana przez accessibilityLabel w iOS i contentDescription w Android
  • Label powinien być zgodny z widocznym tekstem elementów tekstowych; dla nietekstowych (ikony, obrazy) ustawiany ręcznie
  • Hint odpowiada na pytanie „Co się stanie?” i nie powiela Label — te właściwości mają różne role
  • Każdy Label musi być unikalny na ekranie; powielanie dezorientuje użytkownika czytnika ekranu
  • Lokalizacja etykiet jest obowiązkowa przez NSLocalizedString (iOS) i @string (Android)
  • Testuj Label automatycznie przez testy UI (XCUIApplication, AccessibilityCheckRule) i ręcznie przez VoiceOver
  • Elementy dekoracyjne ukrywaj przez isAccessibilityElement = false lub importantForAccessibility = "no"

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również