Search code examples
iosuikitaccessibilityios14voiceover

Prevent UIButton showsTouchWhenHighlighted from altering VoiceOver description


Setting showsTouchWhenHighlighted, e.g. via the IB option "Shows Touch On Highlight," on a button without a title will alter the VoiceOver description. After reading the accessibility label, VoiceOver beeps and announces a description of the image. Is there a way to disable this behavior?


Solution

  • Setting the accessibilityContainerType value to UIAccessibilityContainerTypeSemanticGroup works and that's great 👏 but I'm not sure that this is the goal of this element.
    Even if a button my be seen as a container, I understood this instance property dealt with data-based containers rather. 🤔

    I looked into your problem that arouse my curiosity and couldn't find out an appropriate solution with the Apple API unfortunately.

    First, I thought that this solution may help but it didn't work as you mentioned in your comment... thanks. 😉

    Apparently, when the showsTouchWhenHighlighted property is used, there's an added view inside the button that renders the glow touch ⟹ this is a UIButtonBarPressedIndicator image you can detect thanks to the Debug Hierarchy in Xcode for instance. 👍

    This new image seems to put the default value of the accessibility trait property of your button image even if you have already changed it programmatically. 🤯

    So, in order to avoid VoiceOver from using the screen recognition and reading out some useless information, I made something very ugly but efficient to reach your goal in the viewDidAppear for instance (see the 'basic operations' sheet of this link):

    myButton.subviews.forEach{$0.accessibilityTraits = .none}
    

    Bad hack due to a native problem of implementation or a simple line of code that anyone can understand, this solution removes every possible VoiceOver screen recognition from the button 🥳... and I'm still interested if you can explain a little bit the reason why your solution works, please. 😉