简体   繁体   中英

react native a11y: grouping elements for better voiceover announcement while still exposing inner accessible elements

As per my current understanding, VoiceOver announces things from left to right, top to bottom, as it assumes that is how a visual user sees content.

(I am yet to understand how voiceover figures out the order exactly, it certainly does not depend on the rendered layout tree. would appreciate any pointers )

In cases where you have an atomic piece of content across multiple rows which you want to be announced together by voiceover, you can group it by adding accessible={true} on the container view. The problem is, this makes any internal interactive elements unavailable for accessibility focus, and only allows a11y focus on this container view.

Consider the below design:

Two cards are shown side by side, each card has a title, subtitle and cta. On screen reader focus, we would ideally want the contents of the first card to be read first, and its CTA announced, and then move to the 2nd card and do the same. What ends up happening with voiceover by default is that it announces title1, title2, subtitle1, subtitle2, cta1, cta2 which doesn't make sense for the user.

To fix this, one way is to make the container view accesible={true}, which has a side effect that the CTA is now unavailable to the accessibility focus, and hence a screenreader user can't reach or click the CTA.

Are there any preferred patterns to solve this?

在此处输入图像描述

EDIT: added example code for each card:

<View style={...} key={...}>
  <Text>{title}</Text>
  <Text>{subtitle}</Text>
  <Button flat secondary onPress={() => onPress(item)}>
    {cta}
  </Button>   
</View>

Check out the UIAccessibilityContainer and in particular the accessibilityElements property.

Those are both Objective-C objects and not react, but hopefully react allows you access to them.

Whilst I can't offer an answer I've tested myself just yet as I'm investigating adding this into our project, I thought I'd drop this in for others as this Gist seems like the answer you need:

https://gist.github.com/louy/6b66c45ae47bb4e3bac5a104dd0649ff

It involves a creating a bridge to implement the commands in @slugolicious' answer from the JS/TS side.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM