Accessibility Label es el nombre de un elemento de interfaz que VoiceOver (iOS) o TalkBack (Android) pronuncian al enfocarse. En iOS, la propiedad se llama accessibilityLabel, en Android — contentDescription para elementos que no contienen texto. Según Apple Developer Documentation, 2024, la etiqueta es la base de la accesibilidad: sin ella, el usuario no puede identificar el elemento. La etiqueta debe ser única dentro de la pantalla y reflejar la esencia del elemento en un lenguaje claro.
Puntos clave
Accessibility Label es una propiedad de cadena que define el nombre de un elemento para las tecnologías de asistencia. Cuando el usuario desliza el dedo por la pantalla con VoiceOver activado, el lector de pantalla lee la etiqueta del elemento enfocado. Sin una etiqueta, el usuario solo escucha el tipo de elemento: “botón”, “imagen” — sin indicar su propósito.
Según Google I/O 2024, “Accessibility Testing”, el 35% de las violaciones críticas de accesibilidad en aplicaciones de tienda están relacionadas con la ausencia o incorrección de las etiquetas. Accessibility Scanner en Android detecta la falta de etiqueta como un error de gravedad máxima.
Una limitación fundamental: la etiqueta no debe contener el tipo de elemento. VoiceOver y TalkBack añaden automáticamente el rol (botón, encabezado, enlace) al anuncio. Si la etiqueta contiene “Botón de enviar”, el usuario escuchará: “Botón de enviar, botón” — duplicación.
WCAG 4.1.2 (nivel A) exige que cada elemento de la interfaz de usuario tenga un nombre, rol y valor determinables mediante programación. Accessibility Label proporciona el nombre. Si falta la etiqueta, el criterio se considera incumplido y la aplicación no supera la certificación básica.
En iOS, accessibilityLabel es heredado por todos los UIView del protocolo UIAccessibility. Si un elemento contiene texto (UIButton con título, UILabel con texto), la etiqueta se establece automáticamente en ese texto. Para UIImageView, controles personalizados y contenedores, la etiqueta debe establecerse manualmente.
Ejemplo para una celda de tabla personalizada:
class CustomTableViewCell: UITableViewCell {
let titleLabel = UILabel()
let priceLabel = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
self.isAccessibilityElement = true
self.accessibilityLabel =
"\(titleLabel.text ?? "") - \(priceLabel.text ?? "")"
}
}
Para UIView personalizados, se puede sobrescribir el getter de accessibilityLabel:
class RatingView: UIView {
var rating: Int = 5
override var accessibilityLabel: String? {
get { return "Valoración: \(rating) de 5" }
set {}
}
}
Apple HIG, 2024 recomienda: si un elemento consta de varios subelementos (por ejemplo, una tarjeta de producto con nombre y precio), combínelos en un único elemento de accesibilidad con una etiqueta compuesta. Establezca isAccessibilityElement = true en el padre y false en los hijos.
Si UILabel usa NSAttributedString, accessibilityLabel por defecto es igual a .string (texto plano). Si necesita pasar un valor semánticamente diferente (por ejemplo, un icono de símbolo se lee como “Estrella” en lugar del carácter ★), establezca accessibilityLabel explícitamente. VoiceOver no lee los caracteres Unicode de forma significativa.
En Android, contentDescription funciona como etiqueta para ImageView, ImageButton y vistas personalizadas. Para TextView y Button con texto integrado, no es necesario establecer contentDescription — TalkBack lee el texto automáticamente.
Configuración mediante programación con Kotlin:
binding.iconStar.contentDescription = "Producto en favoritos"
// Para una View personalizada con múltiples elementos
binding.customCard.setContentDescription(
"\(title) por \(price)")
En XML para elementos decorativos:
<ImageView
android:contentDescription="@null"
android:src="@drawable/divider"
android:importantForAccessibility="no" />
La propiedad importantForAccessibility = “no” excluye completamente el elemento del árbol de accesibilidad. En iOS, el equivalente es isAccessibilityElement = false.
En Jetpack Compose, la etiqueta se define mediante el modificador semantics:
Image(
painter = painterResource(R.drawable.ic_search),
contentDescription = "Buscar productos",
modifier = Modifier.semantics {
contentDescription = "Buscar productos"
}
)
En Compose, contentDescription es un parámetro obligatorio para Image — sin él, el código no se compila (advertencia). Esto mejora forzosamente la accesibilidad a través del diseño de la API.
Accessibility Label responde a la pregunta “¿Qué es este elemento?”. Hint (accessibilityHint en iOS, texto adicional en contentDescription en Android) — “¿Qué sucederá al interactuar?”. VoiceOver los anuncia secuencialmente: primero la etiqueta, luego el Hint.
Ejemplo para un botón de eliminar:
Según Deque University, 2024, la separación adecuada de Label y Hint mejora la tasa de finalización de tareas para usuarios de VoiceOver en un 28%. Los usuarios con discapacidades cognitivas dependen especialmente de Hint: al no estar seguros de pulsar “Eliminar” sin explicación, el 40% rechaza la acción.
Un error frecuente: escribir “Botón de eliminar” en la etiqueta en lugar de “Eliminar”. El tipo de elemento (Botón) lo añade VoiceOver automáticamente a través de un rasgo. Como resultado, el usuario escucha: “Botón de eliminar, botón” — duplicación. Etiqueta correcta: “Eliminar”, Hint: “Elimina la foto seleccionada”.
La localización de etiquetas es obligatoria — se realiza mediante mecanismos estándar: NSLocalizedString en iOS, recursos de cadena @string/ en Android. Nunca establezca una etiqueta mediante concatenación en inglés sin localización.
Reglas para una buena etiqueta, basadas en W3C WCAG 2.2:
Use un único glosario para las etiquetas en toda la aplicación. Si en una pantalla pone “Favoritos” y en otra “Marcadores”, el usuario se desorienta. Cree una tabla de términos de accesibilidad — coordine con diseñadores y localizadores.
Para campos de entrada (UITextField, EditText), la etiqueta debe coincidir con el marcador de posición o la etiqueta del campo. Sin embargo, el marcador de posición a menudo desaparece después de introducir texto. Use accessibilityLabel para el nombre permanente y accessibilityValue para el contenido actual del campo — este es el estándar WCAG 4.1.2. Solución: establezca accessibilityLabel estáticamente (igual a la etiqueta del campo) y accessibilityValue dinámicamente (igual al texto introducido). En iOS esto es automático, pero para campos personalizados — manualmente sobrescribiendo accessibilityValue. Verifique que VoiceOver lea: “Correo electrónico, ejemplo@dominio.com, campo de texto” en lugar de “, campo de texto”.
Las pruebas automatizadas son la única forma de garantizar la corrección de las etiquetas en todas las pantallas. iOS proporciona XCUIApplication con acceso a .label, Android — AccessibilityCheckRule y setContentDescription.
Ejemplo de prueba para 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,
"Se encontraron etiquetas duplicadas")
}
Ejemplo para Android con Espresso:
@Test
fun testButtonHasAccessibilityLabel() {
onView(withId(R.id.btnSubmit))
.check(matches(
withContentDescription(containsString("Enviar"))
))
}
Pruebas manuales: active VoiceOver (iOS) o TalkBack (Android) y deslice hacia la derecha por todos los elementos de la pantalla. Cada elemento debe recibir un anuncio significativo. Si solo escucha “botón” o “imagen” — falta la etiqueta.
Después de configurar la etiqueta, los usuarios de VoiceOver pueden usar el rotore para navegación rápida: modos “Botones”, “Encabezados”, “Enlaces” y otros. Si la etiqueta está configurada correctamente, VoiceOver incluye el elemento en el modo de rotore correspondiente. Verifique que todos los botones sean visibles en el modo “Botones”, todos los encabezados en “Encabezados”.
La etiqueta también afecta la búsqueda de VoiceOver. El usuario puede escribir una palabra en el modo de búsqueda y VoiceOver moverá el foco al elemento con una etiqueta coincidente. Por lo tanto, las etiquetas deben contener palabras clave que el usuario buscará.
Añada la verificación de etiquetas al pipeline. En iOS, use XCUITest con fastlane scan. En Android, use Accessibility Test Framework con la regla AccessibilityCheckRule que detecta contentDescription vacíos. Esto evita regresiones al fusionar nuevas pantallas.
Preguntas frecuentes
Label identifica el elemento (“Buscar”), Hint explica el resultado de la acción (“Abre la pantalla de búsqueda”). VoiceOver anuncia la etiqueta inmediatamente al enfocar, y Hint en el modo de descripciones detalladas.
En iOS, UILabel obtiene automáticamente un accessibilityLabel igual a su texto. No se necesita configuración adicional. En Android, TextView se comporta de manera similar.
Establezca isAccessibilityElement = true en la vista principal y sobrescriba accessibilityLabel, devolviendo el texto concatenado de los elementos secundarios. Para componentes complejos, use concatenación con un separador.
Añada contexto a los elementos repetidos: “Comprar iPhone 15”, “Comprar iPhone 15 Pro”. Automatice la verificación mediante pruebas de UI — recolecte todas las etiquetas y verifique que no haya duplicados.
No. Para ocultar un elemento, use isAccessibilityElement = false en iOS o importantForAccessibility = “no” en Android. Una etiqueta vacía no oculta el elemento — el lector de pantalla leerá “sin título”.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también