Saltar al contenido

Accesibilidad y localización

Una app de nivel dios funciona para todos y en todos los idiomas. VoiceOver, Dynamic Type y catálogos de strings: hazla accesible y global casi gratis.

La diferencia entre una app buena y una excelente muchas veces no se ve: es que una persona ciega puede usarla con VoiceOver, que el texto crece para quien lo necesita, y que se siente nativa en cinco idiomas. SwiftUI te da mucho de esto gratis; el resto, con poco esfuerzo.

  • Accesibilidad básica: labels, hints y traits.
  • Dynamic Type: texto que se adapta.
  • Localizar tu app a varios idiomas.
  • Catálogos de strings modernos.

Accesibilidad: SwiftUI ayuda de serie

SwiftUI genera información de accesibilidad automáticamente: un Button("Guardar") ya lo lee VoiceOver. Pero cuando usas iconos o vistas personalizadas, ayúdale con contexto:

SWIFT
Image(systemName: "trash")    .accessibilityLabel("Eliminar")            // qué es    .accessibilityHint("Borra la tarea seleccionada")   // qué hace// agrupar elementos como uno solo para VoiceOverVStack {    Text("Total"); Text("42 €")}.accessibilityElement(children: .combine)      // se lee "Total, 42 euros"

Accesibilidad no es una función extra: es respeto

Es fácil pensar en la accesibilidad como un “por si acaso”, pero millones de personas dependen de VoiceOver, del texto grande y del alto contraste para usar su teléfono. Una app inaccesible sencillamente no existe para ellas. Y lo mejor: SwiftUI hace el 80% del trabajo solo, así que el esfuerzo de cubrir el 20% restante —etiquetar tus iconos, agrupar lo que va junto— es mínimo comparado con el impacto. Probar tu app con VoiceOver activado una vez te abre los ojos a cómo la vive otra gente. Hazlo.

Dynamic Type: texto que respira

Usa los estilos de fuente semánticos (.body, .headline, .title) en vez de tamaños fijos, y tu texto escalará con la preferencia del usuario:

SWIFT
Text("Título").font(.title)        // BIEN: escala con Dynamic TypeText("Cuerpo").font(.body)// Text("X").font(.system(size: 14))  // MAL: tamaño fijo, no se adapta

Alguien con baja visión que sube el tamaño del texto del sistema verá tu app crecer con él, sin que hagas nada más.

Localización: una app, muchos idiomas

Todo texto literal en SwiftUI es, por defecto, una LocalizedStringKey. Eso significa que ya está listo para traducirse:

SWIFT
Text("Bienvenido")      // esto ya es una clave localizable

Catálogos de strings

En Xcode moderno, añades un String Catalog (.xcstrings): Xcode recopila automáticamente todos los textos de tu app y te da una tabla para traducir cada uno a cada idioma, con seguimiento de qué falta:

Recolección automática

Xcode extrae todos los Text("…") de tu código al catálogo. No mantienes listas a mano.

Un idioma por columna

Añades idiomas y rellenas las traducciones en una tabla, con estado (pendiente, hecho, revisar).

Plurales y variantes

Maneja “1 mensaje” vs “3 mensajes” correctamente en cada idioma, con sus reglas.

Localiza desde el principio, no al final

Retrofit de localización a una app terminada es doloroso: textos concatenados a mano, formatos de fecha y número cableados, capturas de pantalla que hay que rehacer. Si desde el inicio usas Text con literales (ya localizables), formateas fechas y números con las APIs del sistema (.formatted()), y evitas construir frases pegando trozos, cuando quieras añadir un idioma será casi solo rellenar el catálogo. La localización barata empieza con buenos hábitos, no con una fase final.

Para todos y en todas partes

  1. Añade .accessibilityLabel a un botón de solo icono.
  2. Agrupa un par de textos con .accessibilityElement(children: .combine).
  3. Activa VoiceOver en el simulador y navega tu app con él.
  4. Usa fuentes semánticas (.body, .title) y sube el Dynamic Type para ver el texto crecer.
  5. Añade un String Catalog y una segunda lengua a un proyecto de prueba.