Search code examples
swiftaccessibilityuinavigationbarvoiceover

Voice over still highlight bar button when accessibility element is set to false


In my navigation bar, there are some bar button items in it. One of them only display an image with is the app logo and have no actions when user click it.

When I enabled voiceover, every time I start the app it will speak out the label and type of the button.

So I tried to disable it by the following code:

    appIconButton.accessibilityElementsHidden = true
    appIconButton.isAccessibilityElement = false
    appIconButton.accessibilityValue = ""
    appIconButton.accessibilityLabel = ""
    appIconButton.accessibilityTraits = .notEnabled

However, voiceover somehow still can highlight the button, and say dimmed button. I have no idea what I miss to prevent the bar button from recognized by voiceover.


Solution

  • The UIBarButtonItem added in the navigation bar belong to a private class _UIButtonBarButton (thanks to the Accessibility Inspector for instance) you can't handle as you wish like views for instance. 😵‍💫

    Personally, I always follow these instructions when I deal with a navigation bar by including custom elements for a11y. 🤓

    To find out a solution for your initial situation, I created a blank project defined hereafter: enter image description here

    I put the code in the view controller as follows:

    @IBOutlet weak var navBar: UINavigationBar!
    @IBOutlet weak var myPlusButton: UIBarButtonItem!
    @IBOutlet weak var myBackButton: UIBarButtonItem!
    
    
    override func viewDidAppear(_ animated: Bool) {
        
        super.viewDidAppear(animated)
        
        var a11yRightBarButton: UIBarButtonItem?
        
        let a11y = UILabel()
        a11y.text = "OK"
        a11y.sizeToFit()
        
        a11yRightBarButton = UIBarButtonItem(customView: a11y)
    
        a11yRightBarButton?.isAccessibilityElement = false
        //if true, the following attributes will be taken into account.
        a11yRightBarButton?.accessibilityTraits = .button
        a11yRightBarButton?.accessibilityLabel = "validate your actions"
        
        navigationItem.setLeftBarButton(myBackButton, animated: false)
        navigationItem.setRightBarButtonItems([myPlusButton,a11yRightBarButton!], animated: false)
        
        navBar.setItems([navigationItem], animated: false)
    }
    

    ... and I get the final results with VoiceOver without reading out nor selecting the desired element (the "OK" button). 👍 enter image description here