Elbrinner da Silva Fernandes

Blog sobre Xamarin, MVVMCROSS y UWP (Plataforma universal de Windows)

Accesibilidad con Xamarin.Forms

Accesibilidad con Xamarin.Forms

API Xamarin Forms

Xamarin.Forms usa controles nativos que de forma natural son accesibles, a demás cuenta con una API de accesibilidad que cubre muchos de los problemas de accesibilidad que pueden existir en una aplicación. Vamos a ver en detalle que podemos hacer, la API cuenta con 4 propiedades que debemos agregar en los controles mediante XAML o C#.

  • AutomationProperties.HelpText
  • AutomationProperties.IsInAccessibleTree
  • AutomationProperties.LabeledBy
  • AutomationProperties.Name

HelpText: Utilizamos para orientar al usuario lo que vamos hacer.

IsInAccessibleTree: Permite indicar si un elemento será usado por el lector de pantalla o no.

LabeledBy: Permite que otro elemento visual defina información de accesibilidad. No hace nada en IOS.

Name: Permite indicar al usuario el nombre del elemento para el lector de pantalla.

 

Ahora que ya conocemos lo que hace la API de Xamarin.Forms, a continuación, voy a contar mi experiencia y los puntos principales a tener en cuenta para que tu aplicación sea accesible.

 

Textos

El diseño, el tamaño de los elementos y los colores es la base que necesitamos para empezar. Vamos a ver algunos problemas relacionado con esto.

Problemas de contraste:

Imagen con texto con poco contraste

Al usar la herramienta Test accesibilidad de Android, recebemos la siguiente notificación.

Captura con problemas de accesibilidad en el contraste

La relación de contraste del texto del elemento es 4,26. Esta relación se basa en un color de primer plano estimado de #5A7B99 y un color de fondo estimado de #FAFAFA. ¿Por qué no utilizas una relación de contraste superior a 4,50 para textos de pequeño tamaño o a 3,00 para textos de gran tamaño.

Si tienes buena visión, es fácil asumir que todas las personas perciben el color o la legibilidad del texto de la misma manera que tú — pero, por supuesto, eso no es real.

Como puedes imaginar, algunas combinaciones de colores que a algunas personas les resultan fáciles de leer les resultan difíciles o imposibles a otras. Esto se suele reducir a color contraste, la relación entre la luminosidad de los colores de primer plano y de segundo plano. Cuando los colores son similares, la relación de contraste es baja. Cuando son diferentes, la relación de contraste es alta.

Imagen con comparaciones de contraste en los textos

Se recomiendan una relación de contraste (mínima) AA de 4.5:1 para todo el texto. Se hace una excepción para texto muy grande (120 a 150% más grande que el texto de cuerpo predeterminado), para el que la relación puede disminuir a 3:1. 

 

Evitar el tamaño fijo en las fuentes:

Uno de los problemas más frecuentes, es no respetar lo que el sistema operativo ya hace por nosotros a nivel de accesibilidad. Cuando agregando el tamaño de la fuente fijo, estamos pisando las preferencias de los usuarios.

Texto con tama fijo en XAML

Al cambiar la configuración en accesibilidad, no va a sufrir ningún cambio, porque hemos puesto los valores como fijo y fijo, se quedan.

Configuraci.

En lugar de usar tamaños fijos, se recomida usar los estilos base ya definidos en Xamarin.Forms.

 

También se puede aplicar el tamaño de la fuente según los valores disponible en el sistema.

Ejemplo:

 

Fuente con valores de la interfaz de Xamarin.Forms. No usa valores fijos.

Parece fácil verdad, hay un pero, cada sistema operativo implementa el tamaño y los estilos de una forma diferente.

Los mismos estilos se ver de la siguiente forma:

Estilos del sistema, se ver de forma muy distintas

 

Como se puede apreciar en la imagen superior, son muy distintos para IOS, Android y UWP.

Con el tamaño definido en los sistemas, pasa algo parecido, actualmente hay 9 valores disponibles como se puede ver en la imagen de abajo:

Miembro iOS Android UWP
Default 16 14 14
Micro 11 10 15.667
Small 13 14 18.667
Medium 16 17 22.667
Large 20 22 32
Body 17 16 14
Header 17 96 46
Title 28 24 24
Subtitle 22 16 20
Caption 12 12 12

Como no existe un estándar, la única forma que me ocurre para solventar este problema es aplicar el tamaño según la plataforma de la siguiente manera:

OnPlatform x:Key="Font-s-1" x:TypeArguments="x:String"
  On Platform="iOS" Body
  On Platform="Android" Medium
  On Platform="UWP" Micro
OnPlatform

 

No transmitas información solo con color

Existen alrededor de 320 millones de usuarios con deficiencia de visión en color. Alrededor de 1 de 12 hombres y 1 de 200 mujeres tienen alguna forma de "daltonismo", lo que significa que alrededor de 1 de cada 20, o el 5%, de tus usuarios no verán tu sitio en la forma que deseas. Cuando confiamos en el color para transmitir la información. Ejemplo:

Muchas veces indicando con color verde, algo que está bien y en rojo cuando está mal. Es importante que está información sea transmitida de otra forma, además de los colores.

Listado de alumnos aprobados que muestra en verde los aprobados y en rojos los suspensos

Imágenes y botones:

Los botones deben tener un tamaño suficiente para que cualquier usuario pueda activarlo sin problema. El tamaño mínimo de objetivo táctil recomendado es de alrededor de 48 píxeles independientes del dispositivo. Por ejemplo, a pesar de que un ícono tenga un ancho y un alto de 24 px, puedes usar relleno adicional para llevar el tamaño del objetivo de presión a hasta 48 px. El área de 48x48 píxeles corresponde a alrededor de 9 mm, que es alrededor del tamaño del área de la yema del dedo.

 

Los objetivos táctiles también deberían tener un espacio de alrededor de 8 píxeles de separación, en orientación horizontal y vertical, de manera que el dedo del usuario, al presionar un objetivo de presión, no toque intencionalmente otro objetivo de presión.

 

La imagen debe tener como minimo 48px de ancho y de altura.

 

Botones con imágenes usando TapGestureRecognizer

De forma predefinida, el lector de pantalla ignorar este elemento. Para que esto no ocurra, debemos agregar los atributos AutomationProperties en la imagen para decir que se debe tener en cuenta y lo que es. Ejemplo en la imagen.

Agregando las propiedades de Xamarin Forms en una imagen, para que funciona como bot y el lector de pantalla lo reconozca

*Al realizar pruebas en los simuladores de IOS, me ignoraba, pero al usar dispositivos (Iphone 6 plus) el resultado ha sido algo distinto. El lector de pantalla voiceover, reconocía el botón en la pantalla y se podía hacer clic. Es importante probar en todos los entornos y buscar la coherencia entre todas las plataformas. En este caso, por más que IOS funciona en dispositivo reales, Android no. Así que debemos agregar el atributo de accesibilidad.

 

Otro caso para tener en cuenta con las imágenes es que ni siempre queremos mostrar todas, hay casos como pueden ser los iconos que no aporta ningún valor al describirlo, su única función es hacer la aplicación más bonita, estos iconos debemos ignorar para el lector de pantalla porque perjudica la experiencia del usuario. Ejemplo de una pantalla de este tipo abajo:

 

Como se puede apreciar, no tiene sentido describir "icono de accesibilidad" y luego decir al usuario, accesibilidad. Es redundante, así que debemos poner la propiedad AutomationProperties.IsInAccessibleTree a false.

Me falta algo más para una experiencia completa con Xamarin.Forms

Imaginemos que tenemos una zona o varias zonas de nuestra App cuyo contenido se añade, elimina, actualiza o modifica sin intervención del usuario. Es lo que llamamos una live region, una zona viva de la aplicación. Infelizmente, Xamarin.Forms no lo implementa, pero tenemos la suerte de tener acceso a las API nativa de cada plataforma.  

Vamos a verificar como funciona en los distintos sistemas, empezando por el HTML5.

  • HTML5, hace uso de WAI-ARIA, que no deja de ser propiedades que van dentro de las etiquetas HTML, que informa el lector de pantallas sobre las actualizaciones en las live region.
  • Android, funciona similar al HTML5, se debe agregar las propiedades especificas de accesibilidad en el código XML del control.
  • UWP, similar a Android y HTML5, hace uso de propiedades en el XAML del control.
  • IOS, se debe usar el método postNotification, está solución es muy distinta a los demás sistemas.

 

Aquí tenemos un pequeño problema, como IOS lo hace de forma tan distinta, no podemos extender los controles, porque no seria suficiente para IOS. Por otro lado, no existe ningún método similar a “postNotification” en Android y UWP, si existe, yo no conozco.

Antes de continuar, quiero explicar porque creo fundamental implementar las live region.

  • Cuando enviamos los datos al servidor, esta operación puede tardar, en este caso considero necesario indicar al usuario que estamos haciendo, para que tenga en cuenta que está operación puede tardar unos segundos. De forma visual se ver claro que la aplicación está realizando algo con el componente de progreso entre otros, pero al usar el lector de pantalla, no llega ninguna información extra al usuario.
  • Cuando actualizamos los valores de una lista, considero fundamental indicar al usuario que los datos ya fueran cargados. Es el mismo caso que el anterior, la mayoria de las aplicaciones permiten actualizar la lista haciendo uso del evento "Pull To Refresh", en Xamarin Forms cuando la operación empieza o finaliza, no indica de ninguna forma al lector de pantalla.

 

*Al probar en simulador en IOS, al actualizar una lista, el lector de pantalla no hace nada. Pero otra vez más, al probar en un teléfono (Iphone 6 plus), el comportamiento ha sido otro. El lector de pantalla indica el número de elementos de la lista. No es la mejor experiencia, pero ya es algo. Al probar en Android, no notifica el lector de pantalla en ningún de los 2 terminales que he probado.

 

Tengo un "prototipo de solución" para estos casos. No es una solución definitiva, pero es mejor que nada de cara al usuario hasta encontrar un solución mejor.

Lo que vamos hacer, es definir un servicio para verificar si el lector de pantalla esta activado, si esta activado vamos enviar un texto en las acciones que queremos notificar al lector de pantalla.

 

Lo primero es crear la interfaz que vamos a usar en Core.

public interface IAccessibility
{
  void PostVoiceOver(string textToSpeak);
  bool IsVoiceOverRunning();
}

En siguiente paso es implementar en plataforma:

IOS:

[assembly: Dependency(typeof(Accessibility))]
namespace AccesibilidadDemo.iOS.Services
{
    public class Accessibility : IAccessibility
    {
        [DllImport(Constants.UIKitLibrary, EntryPoint = "UIAccessibilityPostNotification")]
        public extern static void PostNotification(uint notification, IntPtr id);

        public void PostVoiceOver(string textToSpeak)
        {
            if (IsVoiceOverRunning())
            {
                PostNotification(1008, new NSString(textToSpeak).Handle);
            }
           
            
        }

        public bool IsVoiceOverRunning()
        {
            return UIAccessibility.IsVoiceOverRunning;
        }
    }
}

 

Android:

[assembly: Xamarin.Forms.Dependency(typeof(Accessibility))]
namespace AccesibilidadDemo.Droid.Services
{
    public class Accessibility : IAccessibility
    {
        Context context = Forms.Context;

        public bool IsVoiceOverRunning()
        {

            AccessibilityManager am = (AccessibilityManager)Android.App.Application.Context.GetSystemService(Context.AccessibilityService);
            if (am != null & am.IsEnabled)
            {
               var serviceInfoList = am.GetEnabledAccessibilityServiceList(FeedbackFlags.Spoken);
                if (serviceInfoList!=null)
                    return true;
            }
            return false;
        }

        public void PostVoiceOver(string textToSpeak)
        {
            Toast.MakeText(context, textToSpeak, ToastLength.Short).Show();
        }
     
    }
}

 

Como se puede apreciar, en el caso de Android estoy enviando un Toast. Solo se envía si el lector de pantalla está activado, de forma que no molesto los usuarios que hace el uso de la aplicación sin ninguna necesidad especial y  aporto algo más de información al usuario con lector de pantalla.

 

Herramientas de apoyo

Por último, recomiento el uso de 2 aplicaciones que puede ayudar en la construción.

Funkify

Te ayuda a ponerte en el lugar de un usuario con problemas de accesibilidad. 

Se puede instalar el programa para hacer las simulaciones en el enlace de abajo.

http://www.funkify.org/

 

Test de Accesibilidad

Test de Accesibilidad escanea la pantalla en la que te encuentras y te sugiere mejoras en la accesibilidad de tu aplicación. Para ello, se tienen en cuenta los siguientes factores:

  • Etiquetas de contenido
  • Tamaño de los elementos táctiles
  • Elementos en los que se puede hacer clic
  • Contraste de texto e imagen

La aplicación se puede descargar aquí:

https://play.google.com/store/apps/details?id=com.google.android.apps.accessibility.auditor

 

 

 

Elbrinner da Silva Fernandes Elbrinner da Silva Fernandes
Consultor Xamarin, experto en mobilidad en everis España.
Madrid Spain

Xamarin Certificado

Xamarin Master

Certificación Solutions developer App Builder

Certicación Solutions Associate Web applications

Microsoft Active Professional

Microsoft Professional

Specialist programaming in C#

Specialist programaming in HTML5 with JavaScript & CSS3

Planet Xamarin