Accesibilidad en aplicaciones
7 de mayo de 2024
¿Qué es la accesibilidad en aplicaciones móviles?
La accesibilidad en las aplicaciones se refiere a la capacidad de asegurar que nuestra app esté disponible para el mayor número de personas, considerando las necesidades específicas de los usuarios. Este aspecto debería ser una de las primeras consideraciones durante el desarrollo de una aplicación móvil.
Sin embargo, usualmente este punto no se toma en cuenta al principio del desarrollo, algo que deberíamos cambiar. En España, casi toda la población posee un dispositivo móvil y una gran parte de ellos tienen algún tipo de discapacidad visual. Si nuestras aplicaciones no son accesibles para este grupo de personas, no solo perderíamos una gran cantidad de usuarios, sino que también estaríamos siendo injustos, puesto que todos los usuarios, independientemente de sus condiciones físicas, deberían tener la posibilidad de acceder a los mismos servicios a través de diferentes adaptaciones.
En España, casi un millón de personas tienen algún tipo de discapacidad visual. Es crucial promover la creación de aplicaciones accesibles, para todos los usuarios, independientemente de sus características físicas, mediante adaptaciones adecuadas.
Según un informe publicado por la administración electrónica, en un estudio realizado en 18 aplicaciones, solo el 28% de las mismas cumplían todos los requisitos de accesibilidad para personas con discapacidad visual.
Desde un punto de vista técnico, la creación de aplicaciones accesibles debe ser una prioridad desde el inicio del desarrollo incluyendo la definición de funcionalidades y el diseño de la aplicación. En esta línea, el uso de frameworks de accesibilidad no suele limitar la compatibilidad con versiones específicas del sistema operativo, lo que amplía el potencial de usuarios de la aplicación.
Los frameworks de accesibilidad tanto de iOS como Android permiten que las personas con algún tipo de discapacidad puedan utilizar las aplicaciones sin excesiva dificultad. Es importante tener en cuenta que, aunque estos frameworks tienen muchas opciones que permiten hacer accesibles las aplicaciones, algunos diseños no están pensados con ese fin. Para conseguir esto, es fundamental considerar la accesibilidad tanto en el diseño de la aplicación como en el desarrollo de la misma. Existen numerosas herramientas y técnicas que permiten mejorar la accesibilidad de las aplicaciones para personas con discapacidad visual. En este artículo, nos centraremos en VoiceOver y TalkBack en iOS y Android respectivamente.
Funcionamiento
Las herramientas de accesibilidad funcionan mediante un foco que se desplaza por la pantalla y va leyendo al usuario los textos o funcionalidades de los elementos en los que se detiene.
Recomendaciones de accesibilidad para aplicaciones móviles
Orden del foco
Los usuarios que utilizan la accesibilidad en aplicaciones están acostumbrados a que el foco empiece en la parte superior izquierda de la pantalla y que, al deslizarse por ella, se mueva de izquierda a derecha entre los elementos. En resumen, debería iniciar en la esquina superior izquierda y terminar en la inferior derecha.
Orden foco accesibilidad apps
Es posible que en ciertas ocasiones queramos que el orden del foco cambie excepcionalmente por necesidades de usabilidad. En este caso podemos notificar a los frameworks de accesibilidad el nuevo orden:
iOS
UIKit
Es posible cambiar el orden de los elementos accesibles en cualquier vista modificando la propiedad: accessibilityElements disponible en cualquier elemento que implemente UIView. En el array de elementos, se deberá respetar el orden requerido por la aplicación.
@MainActor
Var accessibilityElements: \[Any\]? { get set }
SwiftUI
En este caso, se puede realizar aplicando el modificador: accessibilitySortPriority(_:). A cualquier View. Recibe un Double como parámetro indicando la prioridad dentro de la View que contenga la vista a la que queremos modificar la prioridad.
func accessibilitySortPriority(\_ sortPriority: Double) -> ModifiedContent<Self, AccessibilityAttachmentModifier\>
Android
XML
Se pueden emplear diversas técnicas para modificar el orden de los elementos accesibles, una de ellas es hacer uso de la propiedad android:accessibilityTraversalAfter y android:accessibilityTraversalBefore disponible en cualquier View.
En android:accessibilityTraversalAfter le indicamos el ID de la vista específica que debería ser la siguiente en el orden de accesibilidad después de la vista actual.
En android:accessibilityTraversalAfter le indicamos el ID de la vista específica que debería ser la anterior en el orden de accesibilidad antes de la vista actual.
Compose
En compose usaremos la propiedad semántica transversalIndex para establecer el orden de accesibilidad para cada view.
Column(
modifier = Modifier.semantics { isTraversalGroup = true },
) {
Text(
text = "First",
modifier = Modifier.semantics { traversalIndex = 0f },
)
Text(
text = "Third",
modifier = Modifier.semantics { traversalIndex = 2f },
)
Text(
text = "Second",
modifier = Modifier.semantics { traversalIndex = 1f },
)
}
Unificación de comportamientos
Aunque los usuarios que requieren accesibilidad suelen mantenerse en un sistema operativo, es importante que el movimiento del foco sea consistente en ambas plataformas. Esto hará que un cambio de dispositivo no haga que el usuario tenga que aprender de nuevo a utilizar una aplicación con la que ya estaba familiarizada.
Contraste
Los altos contrastes entre componentes de la aplicación suelen ayudar a los usuarios con discapacidades visuales. La mayoría de estos usuarios prefieren el modo oscuro en las aplicaciones que lo admiten.
Mensaje leído
Cuando utilizamos componentes de texto, Los frameworks de asistencia suelen funcionar bien con componentes de texto, ya que pueden leer su contenido con facilidad., así como en botones leen el título del botón, etc
Pero pueden darse ocasiones en que el mensaje que lee el asistente no sea exactamente el que queremos. Para solventar este caso:
iOS
UIKit
Sobreescribiendo el parámetro accessibilityLabel con el texto que proceda.
var accessibilityLabel: String? { get set }
SwiftUI
Utilizando el modificador .accessibilityLabel:
func accessibilityLabel<S>(\_ label: S) -> ModifiedContent<Self, AccessibilityAttachmentModifer\> where S: StringProtocol
Android
XML
En el caso que deseamos proporcionar un mensaje específico que el talkback pueda leer en lugar del contenido predeterminado de un componente, podemos utilizar el atributo android:contentDescription, pasándole el texto correspondiente.
Compose
El parámetro contentDescription se usa para describir el elemento que deseemos.
@Composable
func ShareButton(onClick: () -> Unit) {
IconButton(onClick = onClick) {
Icon(
imageVector = Icons.Filled.Share,
contentDescription = stringResource(R.string.label\_share)
)
}
}
Mensajes de error y alertas
Para alertas y mensajes de error importantes, deberán cambiar el foco de la herramienta de accesibilidad para notificar a los usuarios con discapacidad de inmediato sobre lo que está sucediendo en la aplicación. Para notificar un cambio repentino del foco:
iOS
UIKit
Es posible mandando una notificación de UIAccessibility. El tipo de notificación, por lo general será .screenChanged para cuando aparecen vistas que ocupan una nueva parte de la pantalla o .layoutChanged para cuando existen cambios importantes de layout. El argumento que espera esta función es la vista a la que el foco deberá cambiar.
static func post(
notification: UIAccessibility.Notification,
argument: Any?
)
SwiftUI
Es posible haciendo uso del property wrapper @AccessiblityFocusState. Asignaremos esta propiedad a una View y cuando el valor cambie, la vista obtendrá el foco. Documentación y ejemplo.
Android
Usando el método announceForAccessibility de View podemos notificar al usuario del cambio ocurrido.
binding.tvErrorMessage.announceForAccessibility(error)
public void announceForAccessibility(CharSequence text) {
throw new RuntimeException("Stub!");
}
Tiempos de visualización
Hay ocasiones en las que se muestran elementos de la aplicación durante un tiempo limitado por seguridad. Es importante considerar que el uso de una aplicación con un framework de accesibilidad puede ser menos ágil, por lo que se recomienda aumentar ligeramente los tiempos de visualización de elementos que aparecen temporalmente, especialmente cuando la accesibilidad está activada en el dispositivo.
Para comprobar si la accesibilidad está activada:
iOS
Haciendo uso de la variable isVoiceOverRunning propia de UIAccessibility:
static var isVoiceOverRunning: Bool { get }
Android
Llamando a isEnabled de la clase AccesibilityManager:
public boolean isEnabled()
Ocultar a la accesibilidad
En todas las aplicaciones, algunos elementos son funcionales mientras que otros son decorativos o no contribuyen a la funcionalidad. Para estos casos, es recomendable ocultar estos elementos a los frameworks de accesibilidad para no saturar a los usuarios discapacitados con información irrelevante. Algunos ejemplos de este tipo de elementos son: Imágenes decorativas, iconos sin funcionalidad…
Para ocultar estos elementos:
iOS
UIKit
Haciendo uso de la propiedad isAccessiblityElement.
var isAccessibilityElement: Bool { get set }
SwiftUI
Ocultando el elemento a la accesibilidad con el modificador: accessibilityHidden(Bool)
Android
XML
Haciendo uso de la propiedad importantForAccessibility:
Elementos no funcionales android xml accesibilidad apps
Compose
Llamando al método invisibleToUser de semantics:
@ExperimentalComposeUiApi
fun SemanticsPropertyReceiver.invisibleToUser(): Unit
Componentes personalizados
En el desarrollo de aplicaciones, a menudo necesitamos crear componentes personalizados que simulan ser un botón u otro tipo de elemento. Aunque los frameworks de accesibilidad frecen indicaciones útiles a los usuarios,a veces es necesario proporcionar información adicional sobre el tipo de elemento en foco.
iOS
Existen numerosas clasificaciones que podemos dar a los diferentes elementos que se muestran en pantalla. Todas estas clasificaciones se hacen a través los UIAccessibilityTraits que son constantes que especifican el tipo de elemento al que se está haciendo foco. Para asignar un trait:
UIKit
Mediante la propiedad accessibilityTraits.
var accessibilityTraits: UIAccessibilityTraits { get set }
SwiftUI
Mediante el modificador accessiblityAddTraits
func accessibilityAddTraits(\_ traits: AccessibilityTraits) -> ModifiedContent<Self, AccessibilityAttachmentModifier\>
Android
XML
En Android hacemos uso de roleDescription. Nos resultará útil para asignar un rol determinado a componentes personalizados.
ViewCompat.setAccessibilityDelegate(binding.lyBaseButtom, object: AccessibilityDelegateCompact() {
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.roleDescription = "Button"
}
})
Compose
@Composable
fun CustomButton() {
Box(
modifier = Modifier.semantics {
role = Role.Button
}
)
}
Agrupación de componentes
Al igual que en el apartado anterior, hay momentos en los que necesitamos crear componentes personalizados que no están disponibles de forma nativa. Esto puede ocasionar un problema con la accesibilidad si no informamos correctamente al framework de qué componentes debe agrupar y leer como uno solo.
Para conseguir esto:
iOS
UIKit
Es posible activando la accesibilidad en la vista contenedora mediante el parámetro isAccessibilityElement = true. Tras esto, tendremos que establecer qué debe leer VoiceOver cuando detecte este contenedor mediante el parámetro: accessibilityLabel.
SwiftUI
Utilizando el modificador .accessibilityElement(children: .combine). Es posible pasar otros parámetros a este modificador para obtener diferentes comportamientos en función de las necesidades. Más información.
Android
XML
Es posible usando el atributo android:screenReaderFocusable del objeto contenedor a true y el atributo android:focusable de cada objeto interno en false. Tener en cuenta que en Android 4.4 (API 19) y versiones anteriores, el atributo android:screenReaderFocusable no está disponible. Deberíamos usar el atributo android:focusable en su lugar.
<ConstraintLayout
android:id="@+id/song\_data\_container" ...
android:screenReaderFocusable="true"\>
<TextView
android:id="@+id/song\_title"...
android:focusable="false"
android:text="@string/my\_song\_title" />
<TextView
android:id="@+id/song\_artist"
android\_focusable="false"
android:text="@string/my\_songwriter" />
</ConstraintLayout\>
Compose
Haciendo uso del parámetro mergeDescendants en el modifier semantics. Así los servicios de accesibilidad seleccionarán sólo el elemento combinado.
Row(modifier = Modifier.semantics(mergeDescendants = true) {}) {
Image(
imageVector = Icons.Filled.AccountCircle,
contentDescription = null // decorative
)
Column {
Text(metadata.author.name)
Text("${metadata.date} \* ${metadata.readTimeMinutes} min read")
}
}
Conclusiones
Al priorizar la accesibilidad desde las primeras etapas del desarrollo y al emplear herramientas como VoiceOver en iOS y TalkBack en Android, aseguramos que nuestra aplicación sea usable por una amplia audiencia, incluyendo aquellos con discapacidades visuales.
Al trabajar con estos principios, no solo estamos promoviendo la equidad y la inclusión digital, también estamos expandiendo significativamente nuestra base de usuarios potenciales.
Como evidencian las prácticas actuales, las empresas adaptan, cada día más, sus servicios y productos para atender a diversos usuarios, cumpliendo así con diferentes normativas y leyes, (como la Nueva Ley de Servicios de Atención al Cliente).
Referencias bibliográficas
NSObject | UIAccessibility. (s. f.). Apple Developer Documentation
https://developer.apple.com/documentation/objectivec/nsobject/uiaccessibility
SwiftUI | Accessible Navigation. (s. f.). Apple Developer Documentation
https://developer.apple.com/documentation/swiftui/accessible-navigation
SwiftUI | Accessibility fundamentals. (s. f.). Apple Developer Documentation
https://developer.apple.com/documentation/swiftui/accessibility-fundamentals
Cómo compilar apps accesibles. (s. f.). Android Developers
https://developer.android.com/guide/topics/ui/accessibility?hl=es-419
Semántica en Compose. (s. f.). Android Developers
https://developer.android.com/develop/ui/compose/semantics?hl=es-419
Accesibilidad en Compose. (s. f.). Android Developers
https://developer.android.com/develop/ui/compose/accessibility?hl=es-419
Demografía de la Baja Visión y de la Ceguera en España. (2015, 27 agosto). Universidad de
Valladolid
https://uvadoc.uva.es/bitstream/handle/10324/14293/TFM-M259.pdf;jsessionid=51E41EC4BE
9F5B0BEFFA068AB83F480?sequence=1
Informe agregado del seguimiento en profundidad de aplicaciones para dispositivos móviles
(2021). Observatorio de Accesibilidad.
https://administracionelectronica.gob.es/PAe/accesibilidad/2021ProfundidadAPPS
Nuestras últimas novedades
¿Te interesa saber cómo nos adaptamos constantemente a la nueva frontera digital?
5 de noviembre de 2024
Innovación de impacto: Cómo evaluar y diseñar productos digitales sostenibles
22 de octubre de 2024
CSRD: Todo lo que debes saber sobre la Directiva de Informes de Sostenibilidad Corporativa
14 de octubre de 2024
PactFlow & Contract Testing: Un caso de uso empresarial
10 de octubre de 2024
David Álvarez, nuevo ESG Manager