A11y VoiceOver: Disable the ability to call the double tap action on the element.

Hi, I am looking for help with the following question.

I have a card element on the screen and currently I have the following behaviour.

When the VoiceOver is enabled, the user can switch between elements inside the card and hear their accessibility label. But also the user is able to double tap on any of the elements and navigate to the detailed page.

I want to disable the ability to perform an action when double tapping on elements but keep reading accessibility labels.

I tried to override action for elements and make it empty.

public struct AccessibilityActionDisable: ViewModifier {
     public func body(content: Content) -> some View {
         content
             .accessibilityAction { }
     }
 }

This does its job and disables the action when you double tap on the element.

Text("24 miles away")
    .modifier(AccessibilityActionDisable())

But there is one side effect. It adds .isButton trait to the element even if it is not a button. And it is not possible to remove this trait, but I really need to.

So, is it possible to disable the accessibilityAction in some way without this side effect ?

Hey there! Based on the view layout in your app and the behavior you'd like to achieve, let's think about solving this from a different perspective.

You should consider making the entire card view and its children one accessibility element, instead of having each child individually focusable by VoiceOver. By combining these, your app will be easier to navigate with VO because it will have fewer elements. Additionally, the grouping of information makes it easier to comprehend compared to having discrete bits of information. This way, you don't need to consider the activation behavior for each child view because the card as a whole is the only focusable element.

You can do this by using the accessibilityElement(children:) modifier on the parent view. This makes the parent view one focusable element, but you have a choice to make about whether the accessibility properties are merged into the parent or not.

The default AccessibilityChildBehavior is ignore, which means the new combined element has no properties and you must assign them yourself using modifiers like .accessibilityLabel() and .accessibilityValue(), which could be "Bondi" and "24 miles away" respectively. Additionally, you may add information about the image description as well.

The other AccessibilityChildBehavior of interest is combine, which tells SwiftUI to automatically merge the accessibility properties of the child views into the parent, and you don't need to set them manually as long as the child views have appropriate accessibility properties already.

Both approaches will achieve great results and the implementation is only slightly different, but it's good to know all of your options :) Check out these docs for more info and examples:

Finally, please check out this Developer article about reducing "clutter" in your app for VoiceOver users (referring to the number of elements to traverse). Note this article's code examples are in Swift, but there are still valuable concepts to learn that you can apply to any language!

A11y VoiceOver: Disable the ability to call the double tap action on the element.
 
 
Q