Checklist de accesibilidad iOS para cumplir la EAA
La Ley Europea de Accesibilidad (EAA) es obligatoria desde el 28 de junio de 2025 para las apps de banca, comercio electrónico, transporte, medios y otros servicios digitales de consumo. En España la transpone la Ley 11/2023, cuyo régimen sancionador —por remisión al Real Decreto Legislativo 1/2013— contempla multas de hasta un millón de euros. Y no, el famoso «período de gracia hasta 2030» no existe para tu app: esa disposición transitoria solo cubre productos que ya se usaban legalmente antes de la fecha.
La norma técnica de referencia es la EN 301 549, que para software se apoya en los criterios WCAG 2.1 de nivel AA. El problema: WCAG está escrito pensando en la web, y traducirlo a una app iOS nativa —UIKit o SwiftUI— es justo la parte que casi nadie documenta en español.
Esta checklist hace esa traducción. Son 27 puntos verificables, organizados en seis bloques, cada uno con su criterio WCAG cuando aplica y una pista de la API de iOS implicada. Úsala para autoevaluar tu app antes de encargar una auditoría, o como lista de control durante el desarrollo.
Publicado: · Actualizado:
Cómo usar esta checklist
Cada punto es una afirmación que tu app cumple o no cumple; no hay medias tintas deliberadamente. Recorre los seis bloques con la app en la mano, VoiceOver activado y el tamaño de texto al máximo. Todo lo que falle es un hallazgo real que un auditor —o un usuario— también encontrará.
Esta checklist cubre lo verificable sin usuarios reales. No sustituye una auditoría completa: los criterios que dependen del contexto, las pruebas con personas usuarias de tecnologías de apoyo y la declaración de accesibilidad quedan fuera, y te contamos por qué al final de la página.
| Bloque | Criterios WCAG | APIs iOS implicadas |
|---|---|---|
| VoiceOver y etiquetado semántico | 1.1.1 · 1.3.2 · 4.1.2 · 4.1.3 | accessibilityLabel, accessibilityTraits, UIAccessibility.post |
| Texto y Dynamic Type | 1.4.4 · 1.4.5 | preferredFont(forTextStyle:), dynamicTypeSize |
| Color y contraste | 1.4.1 · 1.4.3 · 1.4.11 | Asset Catalog (variantes de contraste), accessibilityContrast (UIKit) / colorSchemeContrast (SwiftUI) |
| Interacción táctil y gestos | 1.3.4 · 2.1.1 · 2.4.7 · 2.5.1 · 2.5.4 | accessibilityCustomActions, Full Keyboard Access, focusable() |
| Formularios y flujos transaccionales | 1.3.5 · 2.2.1 · 3.3.1 · 3.3.2 · 3.3.3 | textContentType, keyboardType, anuncios de error |
| Medios, movimiento y contenido dinámico | 1.2.2 · 1.2.5 · 2.3.1 · 2.3.3 | AVPlayer (subtítulos), isReduceMotionEnabled |
VoiceOver y etiquetado semántico
VoiceOver es el lector de pantalla de iOS y el primer filtro de cualquier auditoría. Si un elemento no está etiquetado, no tiene el rol correcto o se lee en un orden absurdo, la app es inutilizable para una persona ciega, por bonito que sea el resto.
-
Todos los elementos interactivos exponen una etiqueta de accesibilidad concisa y descriptiva; ninguna imagen funcional se anuncia como «imagen» a secas ni con el nombre del asset.
(WCAG 1.1.1)
accessibilityLabelen UIKit;.accessibilityLabel(_:)en SwiftUI. Las imágenes decorativas se ocultan conisAccessibilityElement = false/.accessibilityHidden(true). -
Cada elemento anuncia su rol y estado reales: los botones se anuncian como botón, lo seleccionado como seleccionado, lo deshabilitado como atenuado.
(WCAG 4.1.2)
accessibilityTraits(.button,.selected,.notEnabled); en SwiftUI,.accessibilityAddTraits(_:). -
El orden de lectura con VoiceOver sigue la lógica visual y funcional de la pantalla, no el orden accidental de la jerarquía de vistas.
(WCAG 1.3.2)
accessibilityElementsen el contenedor;.accessibilitySortPriority(_:)en SwiftUI. -
Los elementos que forman una unidad de significado (icono + título + subtítulo de una celda) se agrupan y se leen como un único elemento, no como tres paradas sueltas.
shouldGroupAccessibilityChildren/ elemento contenedor con label compuesta;.accessibilityElement(children: .combine)en SwiftUI. -
Los cambios dinámicos de contenido (resultados cargados, errores, actualizaciones en pantalla) se anuncian a VoiceOver sin que el usuario tenga que ir a buscarlos.
(WCAG 4.1.3)
UIAccessibility.post(notification: .announcement, …)/.layoutChanged;AccessibilityNotification.Announcementen SwiftUI. -
Las acciones disponibles por gesto contextual (deslizar para borrar, mantener pulsado) están también expuestas al rotor como acciones personalizadas.
accessibilityCustomActions;.accessibilityAction(named:)en SwiftUI.
Texto y Dynamic Type
Dynamic Type permite al usuario elegir el tamaño de texto de todo el sistema. Una app que lo ignora —o que se rompe al activarlo— excluye a una parte enorme de sus usuarios, y es de lo primero que comprueba cualquier auditor porque se detecta en segundos.
-
Todo el texto de la app escala con Dynamic Type; no hay tamaños de fuente fijos en pantallas de contenido.
(WCAG 1.4.4)
UIFont.preferredFont(forTextStyle:)+adjustsFontForContentSizeCategory = true; en SwiftUI los estilos deFont(.body,.headline…) escalan por defecto. - No hay texto informativo rasterizado dentro de imágenes; todo el texto es texto real que escala y que VoiceOver puede leer. (WCAG 1.4.5) componer texto + imagen en la vista en lugar de assets con texto incrustado.
-
Con el texto ampliado, los layouts crecen en vez de romperse: nada se trunca con «…» perdiendo información, nada se solapa, y las alturas de celda son autoajustables.
Auto Layout sin alturas fijas,
UITableView.automaticDimension; en SwiftUI, evitar.lineLimitrestrictivos y frames rígidos. -
La app es funcional en los tamaños de accesibilidad (AX1–AX5), no solo en los cinco tamaños estándar; donde el layout horizontal deja de caber, se reorganiza en vertical.
traitCollection.preferredContentSizeCategory.isAccessibilityCategory;@Environment(\.dynamicTypeSize)yViewThatFitsen SwiftUI.
Color y contraste
El contraste insuficiente es el fallo más común y el más barato de arreglar. Y el color nunca puede ser el único vehículo de un significado: lo que hoy es «rojo = error» para ti, para una persona con daltonismo es simplemente otro gris.
- El texto normal alcanza un contraste mínimo de 4,5:1 sobre su fondo, y el texto grande y los componentes de interfaz llegan al menos a 3:1 — también en modo oscuro. (WCAG 1.4.3 · 1.4.11) colores semánticos del sistema o Asset Catalog con variantes claro/oscuro; verificar con el Accessibility Inspector de Xcode.
- Ningún estado o información se comunica solo con color: los errores, lo seleccionado y lo activo llevan además icono, texto o cambio de forma. (WCAG 1.4.1) revisión de diseño; SF Symbols como refuerzo no cromático.
-
La app responde a los ajustes de contraste del sistema y no se rompe con Smart Invert: las fotos y el contenido ya oscuro no se invierten.
variantes de alto contraste en Asset Catalog,
UIAccessibility.isDarkerSystemColorsEnabledotraitCollection.accessibilityContrasten UIKit;accessibilityIgnoresInvertColorsy@Environment(\.colorSchemeContrast)en SwiftUI.
Interacción táctil y gestos
Que un control exista no significa que se pueda usar. Objetivos táctiles minúsculos, gestos que exigen dos manos o precisión de cirujano, y pantallas que solo responden a agitar el teléfono son barreras directas para personas con movilidad reducida.
-
Todos los objetivos táctiles miden al menos 44×44 puntos, aunque su representación visual sea menor.
ampliar el área con insets; en UIKit, sobreescribir
point(inside:with:)ohitTest(_:with:)si hace falta; HIG de Apple como referencia. -
Toda función accionada por un gesto complejo o multipunto (pellizcar, arrastrar, deslizar con dos dedos) tiene una alternativa de un solo toque.
(WCAG 2.5.1)
botones alternativos visibles o
accessibilityCustomActions. -
Ninguna función depende de mover el dispositivo (agitar, inclinar) sin una alternativa en pantalla, y la respuesta al movimiento puede desactivarse.
(WCAG 2.5.4)
alternativa de UI a
CMMotionManager/ gesto de agitar; respetar los ajustes del sistema. -
La app es completamente operable con Full Keyboard Access y Switch Control: todo lo interactivo recibe el foco, el foco es visible y no hay trampas de foco.
(WCAG 2.1.1 · 2.4.7)
probar con Full Keyboard Access activado;
UIKeyCommand,canBecomeFocused;.focusable()y@FocusStateen SwiftUI. -
La app funciona en vertical y en horizontal; no se bloquea a una sola orientación salvo cuando es esencial para la tarea (por ejemplo, la captura de un cheque).
(WCAG 1.3.4)
no restringir
supportedInterfaceOrientationssin justificación; en SwiftUI, layouts que se adaptan al tamaño disponible en lugar de asumir una orientación.
Formularios y flujos transaccionales
La EAA aplica sobre todo a servicios con los que el usuario hace cosas: comprar, contratar, pagar, reservar. De poco sirve un onboarding impecable si el formulario de pago es infranqueable con VoiceOver. Este bloque es el que decide si tu app cumple donde de verdad importa.
-
Todos los campos tienen etiqueta visible y persistente; el placeholder nunca es la única etiqueta, porque desaparece al escribir.
(WCAG 3.3.2)
label visible asociada +
accessibilityLabelen el campo; en SwiftUI,TextFieldconLabeledContento label explícita. -
Cuando la validación falla, el error se identifica y se describe en texto junto al campo afectado, y VoiceOver lo anuncia en el momento.
(WCAG 3.3.1)
mensaje de error como texto asociado al campo +
UIAccessibility.post(notification: .announcement, …). - Los errores recuperables ofrecen una sugerencia de corrección concreta («el IBAN debe tener 24 caracteres»), no un genérico «datos inválidos». (WCAG 3.3.3) mensajes de validación específicos por regla.
-
Cada campo declara su propósito y su teclado: el email saca teclado de email y se autorrellena, el código SMS se sugiere solo, la contraseña funciona con gestores.
(WCAG 1.3.5)
textContentType(.emailAddress,.oneTimeCode,.password…) +keyboardType. - Ningún paso del flujo transaccional caduca sin aviso ni posibilidad de ampliar el tiempo, y el flujo completo —del carrito a la confirmación— es operable de principio a fin solo con VoiceOver. (WCAG 2.2.1) avisos antes de expirar sesión con opción de extender; prueba manual del flujo entero con VoiceOver.
Medios, movimiento y contenido dinámico
El contenido audiovisual y las animaciones tienen sus propias reglas: lo que no se oye necesita subtítulos, lo que no se ve necesita descripción, y el movimiento que a ti te parece elegante puede marear —literalmente— a parte de tus usuarios.
-
Todo el contenido de vídeo pregrabado con audio ofrece subtítulos, y el reproductor respeta los subtítulos y ajustes de estilo del sistema.
(WCAG 1.2.2)
pistas de subtítulos en el asset;
AVPlayerlos gestiona con los ajustes del usuario (MACaptionAppearance). -
El vídeo pregrabado con audio ofrece audiodescripción cuando hay información visual que no está ya presente en la banda sonora; a nivel AA, una transcripción no sustituye a la audiodescripción.
(WCAG 1.2.5)
pista de audiodescripción en el asset (
AVMediaCharacteristic.describesVideoForAccessibility); la transcripción accesible es un complemento, no el sustituto. -
La app respeta el ajuste «Reducir movimiento»: los parallax, zooms y transiciones grandes se sustituyen por fundidos o se eliminan.
(WCAG 2.3.3)
Recomendado
UIAccessibility.isReduceMotionEnabled;@Environment(\.accessibilityReduceMotion)en SwiftUI. - Nada en la app parpadea más de tres veces por segundo, incluidos vídeos, animaciones de carga y efectos promocionales. (WCAG 2.3.1) revisión de animaciones y contenido; sin API específica — es una regla de diseño.
Qué no cubre esta checklist (y cuándo necesitas una auditoría)
Ser honestos aquí es parte del trabajo: pasar estos 27 puntos significa que has eliminado las barreras más frecuentes y objetivas, no que tu app «cumple la EAA». Hay tres cosas que una checklist no puede darte:
- Pruebas con personas usuarias reales de tecnologías de apoyo — el orden de lectura puede ser técnicamente correcto y aun así resultar agotador de usar; eso solo lo revela alguien que navega con VoiceOver a diario.
- Los criterios que dependen del contexto de tu app — qué es «texto grande» en tu diseño, qué alternativa tiene sentido para tu gesto, qué flujos son servicios afectados por la EAA y cuáles no.
- La parte formal del cumplimiento — la evaluación documentada frente a EN 301 549 y la información de accesibilidad que el servicio debe poner a disposición del público.
¿Tu app pasa la checklist… o no del todo?
Hacemos auditorías de accesibilidad específicas de iOS nativo —no adaptaciones de auditoría web— con remediación incluida si la necesitas. Desde un diagnóstico inicial hasta el acompañamiento continuo, con precios publicados.
Ver el servicio de accesibilidad iOS (EAA)Preguntas frecuentes
Hablemos de tu reto iOS
Reserva 30 minutos con Francisco José García Navarro, Arquitecto iOS Senior, para revisar tu proyecto. Sin compromiso.