Pièges courants liés aux éléments d'accessibilité et comment les éviter

Chris McMeeking

Par Chris McMeeking

3 février 2016

Deque Logo « U Best Practices »Peut-être que ce scénario vous dit quelque chose : vous travaillez sur votre application iOS et vous vous intéressez de près ou de loin à l’accessibilité. Vous savez un peu comment utiliser VoiceOver et vous jetez un coup d’œil rapide à votre application pour vous assurer qu’elle est accessible. Soudain, vous remarquez un bouton dans un coin. Ce bouton est désactivé tant que l’utilisateur n’a pas renseigné un certain champ de texte. Vous vous dites alors :

Pfff. Je devrais masquer ça à VoiceOver quand il est désactivé. Mais comment faire ?

Après une petite recherche sur Google, vous tombez sur la propriété `isAccessibilityElement`. Vous vous dites :

Super, il me suffit de définirisAccessibilityElementsur NO et le tour est joué. Problème résolu !

Sauf que ce n’est pas le cas. Si vous avez trouvé cela un peu trop simple, eh bien, vous avez raison. Mais malheureusement, j’ai lu plus d’un article sur Stack Overflow qui suivait exactement ce raisonnement. Cela peut sembler être une solution assez simple, mais c’est en réalité un peu plus complexe. C’est ce que je vais aborder dans cet article – en détail – afin que vous puissiez gérer tous les problèmes qui pourraient survenir. Vous comprendrez également pourquoi le simple fait de définir l’élément « accessibility » sur « NO » n’est pas la bonne approche. Voici les points que je vais aborder :

  • Ce que fait réellement la propriété `isAccessibilityElement `.
  • Cas dans lesquels il est nécessaire de remplacer cette propriété.
  • Une question intéressante concernant l'imbrication des éléments d'accessibilité.

Vous trouverez des exemples illustrant les concepts abordés dans cet article (et bien d'autres encore) dans notre application iOS open source « Deque University for iOS ».

Éléments d'accessibilité

Lorsque vous mettez en œuvre l'accessibilité, iOS met à votre disposition plusieurs propriétés. La propriété `isAccessibilityElement`est l'une des plus importantes. Il est très facile de commettre une erreur avec cette propriété, ce qui peut compromettre l'accessibilité de votre application. Et je ne parle pas seulement de problèmes mineurs, mais bien d'une défaillance catastrophique totale. Et ce n'est pas une exagération !

La propriété `isAccessibilityElement`vous permet de contrôler les informations qu’iOS transmet entre votre application et VoiceOver. À présent, VoiceOver s’exécute dans un processus distinct de celui de votre application. Par conséquent, VoiceOver n’a pas accès aux objets `UIView`que vous avez créés. À la place, iOS envoie un ensemble simplifié d’informations, composé des éléments qu’iOS considère comme importants pour l’accessibilité.

isAccessibilityElement = YES

Supposons que la propriété `isAccessibilityElement` soitdéfinie sur `YES`. Il s’agit de la valeur par défaut pour tout contrôle affichant des informations (comme `UIButton`, `UIImageView`, `UILabel`, etc.). L’utilisateur dispose de deux méthodes pour interagir avec ce type d’éléments à l’aide de VoiceOver.  La première consiste à passer le curseur sur n'importe quel pixel situé dans les limites de l'élément. L'autre consiste à balayer rapidement l'écran vers la droite ou vers la gauche, ce qui amène VoiceOver à mettre en surbrillance les éléments d'accessibilité les uns après les autres, comme si l'on appuyait sur la touche Tab du clavier. Une fois qu'un élément est mis en surbrillance, VoiceOver procède à l'annonce de son libellé et lit toutes les informations relatives à ses caractéristiques. Puis, après une pause, il lit l'astuce.

isAccessibilityElement = NON

Si cette propriété est définie sur NO, VoiceOver traitera l’élément comme s’il n’existait pas. Si un utilisateur fait glisser son doigt sur l’élément, celui-ci ne sera pas mis en surbrillance. Si vous utilisez la navigation par gestes, l’élément sera complètement ignoré. Et peu importe les caractéristiques de l’élément ou le niveau de détail de l’étiquette que vous lui avez attribuée. Définir cette propriété sur NO signifie que VoiceOver l’ignorera complètement !  Il s’agit du comportement par défaut des élémentsUIView de base, des contrôles personnalisés héritant directement deUIView, ainsi que d’autres éléments de vue servant de collections pour d’autres éléments enfants.

Vous vous demandez sûrement… et maintenant ?

Remplacer la méthode isAccessibilityElement

En général, les valeurs par défaut de cette propriété sont correctes. À moins d’être un expert en accessibilité connaissant parfaitement les subtilités des WCAG 2.0, il est probablement plus prudent de laisser iOS gérer cela de son côté. Cela dit, il existe des cas où il est nécessaire de remplacer cette valeur. En effet, les choses peuvent vraiment mal tourner si vous ne le faites pas. Vous trouverez ci-dessous quelques cas de figure qui devraient vous aider à y voir plus clair.

Du « OUI » au « NON » : points importants à prendre en compte

Vous envisagez de remplacer cette propriété lorsque la valeur par défaut est « YES » ? Eh bien, vous vous posez peut-être la question de la mauvaise manière. Revenons à l’exemple donné dans l’introduction de cet article. La personne qui travaille sur l’application cherche à faire preuve de considération envers les utilisateurs non-voyants et à masquer certaines informations que le développeur ne juge pas importantes. Le bouton est désactivé. Alors pourquoi un utilisateur non-voyant se soucierait-il d’un bouton désactivé ?

Cette logique pose deux problèmes :

1) Tous les utilisateurs de VoiceOver ne sont pas entièrement aveugles. Lorsque vous déterminez les valeurs à attribuer aux propriétés d’accessibilité, il est important de garder à l’esprit que vous ne vous préoccupez pas uniquement des utilisateurs aveugles de VoiceOver, mais également de ceux qui ont une vision réduite.  Et qu'en est-il des utilisateurs de clavier ? Qu'en est-il des utilisateurs de claviers braille ou d'autres technologies d'assistance ? En masquant ces informations à VoiceOver, vous les masquez non seulement à la navigation gestuelle, mais les utilisateurs voyants qui ont des difficultés à lire le texte de vos éléments ne comprendront pas pourquoi ils ne parviennent pas à sélectionner votre contrôle.

2) Même si un bouton est désactivé, il peut tout de même fournir des informations. En fait, on pourrait même dire qu’un bouton désactivé fournit PLUS d’informations qu’un bouton activé. Quand vous voyez un bouton désactivé sur une page, que pensez-vous ?

Tiens, voilà une commande qui ne sert à rien et que je n'utiliserai jamais.

Ou

Salut, que dois-je faire pour activer cette fonction ?

Il est évident qu'un contrôle désactivé peut fournir de nombreuses informations. En réalité, un contrôle désactivé dans une vue peut en dire long à lui seul.

Les cas dans lesquels vous devriez définir cette propriété sur « NO » sont un peu plus subtils. Le meilleur exemple qui me vient à l’esprit est celui d’une boîte de dialogue modale mal configurée. Si vous configurez correctement votre boîte de dialogue modale, l’utilisateur ne devrait pas pouvoir interagir avec les éléments situés derrière celle-ci. Avant de pouvoir poursuivre la navigation dans votre application, l’utilisateur doit d’abord traiter cette boîte de dialogue modale.

Même si l’utilisateur n’a qu’à cliquer sur « OK », cette action doit tout de même être menée à bien AVANT toute autre interaction. Cela signifie que le fait de se passer des mécanismes iOS permettant une configuration simple et correcte, ou d’opter pour un framework de boîtes de dialogue modales effectuant le dessin manuel des vues, pourrait entraîner des problèmes. Vous pourriez, par exemple, constater que la « superposition » utilisée pour bloquer l’interaction de l’utilisateur n’a pas empêché VoiceOver de sélectionner ces vues. Ce problème est particulièrement fréquent lorsque vous envisagez une navigation par glissement. Dans ce cas de figure, je vous recommande vivement de passer en revue tous les éléments de votre vue principale et de les marquer comme n’étant PAS des éléments d’accessibilité. N’oubliez surtout pas de les remettre tous sur « OUI » une fois que votre boîte de dialogue modale a été fermée !

Du « NON » au « OUI » : une approche plus simple

Les cas où vous devez redéfinir la propriété `isAccessibilityElement` sur `YES` sont beaucoup plus simples. Si vous créez un contrôle personnalisé qui hérite uniquement de`UIView` mais pas du contrôle de base iOS correspondant,vousdevrez peut-être redéfinir cette propriété. Si votre composant présente des informations à l’utilisateur ou accepte des entrées de sa part, il doit être considéré comme un élément d’accessibilité (à l’exception du cas mentionné ci-dessus).  Il existe également un autre cas où il est approprié de définir cette propriété sur YES : lorsqu’un élément sert de conteneur à d’autres éléments d’accessibilité et qu’il est logique de regrouper ces éléments au sein d’un seul élément. Ce scénario doit toutefois être géré avec TRÈS grande prudence.

Éléments d'accessibilité imbriqués

Lorsque vous déterminez la valeur appropriée pour la propriété`isAccessibilityElement`, il est très important de tenir compte de l'effet de l'imbrication d'éléments d'accessibilité au sein d'autres éléments d'accessibilité. Prenons un exemple. Pour cet exemple, supposons qu'un certain style ait été appliqué ; par exemple, notre `childView` est un bouton et notre `parentView` est notre vue principale.

[code language="objc"]
childView.accessibilityLabel = @"Je suis la vue enfant" ;
childView.isAccessibilityElement = YES ;

parentView.accessibilityLabel = @"Je suis le parent" ;
parentView.isAccessibilityElement = YES ;
[parentView addSubview:childView] ;
[/code]

Vous remarquerez ici que les éléments parent et enfant sont tous deux des éléments d’accessibilité.  Que va-t-il se passer ici ? Dans ce cas, l’utilisateur ne pourrait pas accéder à `childView`. À la place, VoiceOver lui permettrait uniquement d’accéder à `parentView`. Pour les utilisateurs aveugles qui utilisent la navigation par gestes, l’élément enfant n’existe tout simplement pas. Pour les utilisateurs malvoyants, il y aurait un bouton à l’écran avec lequel ils ne pourraient pas interagir.

Capture d'écran d'une application comportant des éléments d'accessibilité imbriqués. La fenêtre de l'inspecteur d'accessibilité est ouverte et affiche l'étiquette d'accessibilité « Il s'agit d'un lecteur de musique » d'une vue parente, qui contient des boutons sur lesquels il n'est pas possible de placer le focus individuellement.
Exemple d'éléments d'accessibilité imbriqués. Remarquez que le lecteur principal a le focus. Cependant, si l'on clique sur les boutons, ceux-ci ne peuvent pas recevoir le focus individuellement.

Ce n'est évidemment PAS ce que vous souhaitez dans ce cas précis ! Cependant, il est possible de tirer parti de cet inconvénient. Imaginons que vous ayez une simple fiche de contact. Lorsque vous disposez plusieurs fiches de contact les unes à côté des autres ET que vous permettez une interaction avec chaque élément de la fiche, la situation commence à devenir confuse. Comment savoir à quel contact appartient tel ou tel champ ? Voici un exemple illustrant précisément ce scénario :

Nom, Téléphone

Herman, 000

Henrietta, 111

Si vous parcourez cette liste de contacts en faisant défiler les noms d’un simple geste, comment savoir à qui appartient le numéro 000 ? Est-ce celui d’Herman ou celui d’Henrietta ? Vous souviendrez-vous que les informations sont classées par ordre de nom, puis de numéro de téléphone ? Et si cette liste comptait 500 contacts ?  Et s'il y avait plus d'informations que le simple nom et numéro de téléphone ? Comme vous pouvez le constater, les choses peuvent très vite se compliquer. Regrouper ces informations dans une fiche de contact permettrait vraiment de clarifier la situation ! Dans ce cas, nous pouvons tirer parti d'un élément parent pour rassembler toutes les informations provenant des éléments d'accessibilité qu'il contient via l'étiquette d'accessibilité du parent. Vous pouvez voir ci-dessous une implémentation simplifiée de cette vue contenante :

[code language="objc"]

@implementation DQWrapperView
– (NSString*) accessibilityLabel {

NSMutableString* accessibilityLabel = [NSMutableString new];

for (UIView* view in self.subviews) {

if (view.accessibilityLabel)
[accessibilityLabel appendFormat:@" %@", view.accessibilityLabel];
}
}
@end

[/code]

Capture d'écran d'une application présentant une interface très similaire à celle de l'autre image de cette page. Toutefois, dans ce cas précis, il est possible de sélectionner chaque bouton individuellement.
Remarquez qu'ici, nous avons un bouton et une étiquette regroupés. L'étiquette correspond au texte du bouton ; il est donc logique de sélectionner les deux éléments ensemble.

Vous remarquerez que j'ai rassemblé les libellés d'accessibilité des vues contenues et que je les ai regroupés dans une seule vue. En redéfinissant la propriété « accessibilityLabel », vous n'avez plus besoin de gérer plusieurs chaînes de caractères. Il vous suffit simplement de collecter les informations à chaque fois que la vue est consultée. Cela vous permet de gérer automatiquement toute modification dynamique du contenu.

AVERTISSEMENT : Si vous utilisez cette approche, veillez à bien tenir compte du nombre d'éléments actifs que vous encadrez. Cette approche ne sera pas valide si vous encadrez plus d'un élément. Si vous encadrez plus d'un élément, vous devrez recourir à d'autres méthodes d'association de données.

 

Maintenant que vous comprenez beaucoup mieux comment utiliser les éléments d'accessibilité d'iOS, vous êtes prêt à vous lancer. Ne manquez pas notre prochain article et n'hésitez pas à consulter Deque University pour plus d'informations. Vous pouvez également découvrir un exemple plus complet de mise en œuvre d'une classe de vue « wrapper »en consultant notre projet de framework d'accessibilité open source.

Chris McMeeking

Chris McMeeking

Chris McMeeking est ingénieur logiciel et architecte chez Deque Systems, où il dirige les efforts de développement des produits natifs d’analyse de l’accessibilité mobile de Deque. Son parcours dans le domaine de l’accessibilité a débuté avec un projet mené à l’université du Michigan, le clavier à balayage ASK. Cette application a remporté de nombreux prix, notamment l’Intel Innovator’s Award d’une valeur de 100 000 dollars, la deuxième place au Mobile World Congress et le prix « Student of Da Vinci » décerné par la Fondation pour la sclérose en plaques. Chris est le développeur principal de l’Android Analyzer et un membre actif du groupe de travail chargé d’élaborer ces nouvelles normes d’accessibilité pour les appareils mobiles.

Recevez les articles de blog directement dans votre boîte mail

Pas de bavardages inutiles, mais des informations concrètes sur l'accessibilité, fournies par des experts qualifiés.

Vous acceptez que Deque , utilise et partage des informations conformément à Dequedéclaration de confidentialité. Vous pouvez modifier votre consentement à tout moment en nous contactant.

En savoir plus sur ce sujet

Google I/O et l'impact de l'IA générative sur l'accessibilité

Je suis la conférence Google I/O en ligne depuis 2015. Il s'agit de leur événement phare destiné à tous les acteurs du secteur des technologies, y compris les professionnels de l'accessibilité. Cette année,…

Lire l'article
Blog Google I/O

Deque Ajoute des fonctionnalités de test et de vérification syntaxique React Native à axe DevTools Mobile

Logo de Deque
20 avril 2023 Par Deque Systems

Parmi les nouvelles fonctionnalités, on trouve la prise en charge des tests d'accessibilité automatisés pour les applications développées avec React Native, les nouvelles règles WCAG 2.2 relatives à l'espacement des cibles tactiles, la prise en charge d'iPadOS et l'apprentissage automatique…

Lire l'article
React Mobile