Accesibilidad en aplicaciones

Accesibilidad en aplicaciones

Álvaro Sánchez Pinzón, iOS Developer

Álvaro Sánchez Pinzón

iOS Developer

Ángel Miguel Mac Donald Gainza, Android Developer

Ángel Miguel Mac Donald Gainza

Android Developer

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.

Ordenfocoaccesibilidadapps_.webp 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 }

Documentación

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\>

Documentación

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. 

Documentación

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.

Documentación

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 },  
)  
}

Documentación

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 }

Documentación

SwiftUI

Utilizando el modificador .accessibilityLabel:


func accessibilityLabel<S>(\_ label: S) -> ModifiedContent<Self, AccessibilityAttachmentModifer\> where S: StringProtocol

Documentación

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. 

Documentación

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)  
)  
}  
}

Documentación

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?  
)

Documentación

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!");  
}

Documentación

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 }

Documentación

Android

Llamando a isEnabled de la clase AccesibilityManager:


public boolean isEnabled()

Documentación

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 }

Documentación

SwiftUI

Ocultando el elemento a la accesibilidad con el modificador: accessibilityHidden(Bool)

Android

XML

Haciendo uso de la propiedad importantForAccessibility:

Elementosnofuncionalesandroidxmlaccesibilidadapps.webp Elementos no funcionales android xml accesibilidad apps

Documentación

Compose

Llamando al método invisibleToUser de semantics:


@ExperimentalComposeUiApi  
fun SemanticsPropertyReceiver.invisibleToUser(): Unit

Documentación

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 }

Documentación

SwiftUI

Mediante el modificador accessiblityAddTraits


func accessibilityAddTraits(\_ traits: AccessibilityTraits) -> ModifiedContent<Self, AccessibilityAttachmentModifier\>

Documentación

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"  
}  
})

Documentación

Compose

@Composable  
fun CustomButton() {  
Box(  
modifier = Modifier.semantics {  
role = Role.Button  
}  
)  
}

Documentación

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\>

Documentación

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")  
}  
}

Documentación

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

Álvaro Sánchez Pinzón, iOS Developer

Álvaro Sánchez Pinzón

iOS Developer

¡Hola! Soy Álvaro Sánchez Pinzón, desarrollador iOS en SNGULAR. Soy Ingeniero en Sistemas Audiovisuales, y aunque desde 2019 me centro en el desarrollo de aplicaciones para el ecosistema de Apple, me encanta trastear con todas las tecnologías que están a mi alcance así como enseñar y aprender de los demás todo lo posible.

Ángel Miguel Mac Donald Gainza, Android Developer

Ángel Miguel Mac Donald Gainza

Android Developer

Soy Ángel Miguel Mac Donald Gainza, desarrollador de Android en SNGULAR. Con más de 6 años de experiencia en el sector, disfruto creando aplicaciones innovadoras, útiles y accesibles, y explorando las diversas posibilidades que la tecnología ofrece en nuestro día a día en todos sus ámbitos.


Nuestras últimas novedades

¿Te interesa saber cómo nos adaptamos constantemente a la nueva frontera digital?

La Apificación como motor del cambio en la Modernización de Aplicaciones
La Apificación como motor del cambio en la Modernización de Aplicaciones

Tech Blog

11 de junio de 2024

La Apificación como motor del cambio en la Modernización de Aplicaciones

Gestión de la memoria en Swift
Gestión de la memoria en Swift

Tech Blog

10 de mayo de 2024

Gestión de la memoria en Swift

Contract testing vs testing funcional
Contract testing vs testing funcional

Tech Blog

7 de mayo de 2024

Contract testing vs testing funcional

Deja huella en las personas, no en el planeta
Deja huella en las personas, no en el planeta

Insight

16 de abril de 2024

Deja huella en las personas, no en el planeta