'Setting UIView.isAccessibleElement to true disables clicking of subview in voiceovermode

So I have a custom view controller that displays a dialog with a couple of buttons. When the view appears I want voiceover to read out some basic information describing the dialog. To achieve this I made the parent view to be an accessible element and the subviews which are two buttons are also accessible elements. My problems now is that the buttons are not clickable directly. They must be reached only by swiping right on the screen.

class MyViewController: UIViewController {
    let parent = UIView()
    let button1 = UIButton()
    let button2 = UIButton()

    init() {
        parent.addSubview(button1)
        parent.addSubview(button2)
        parent.isAccessibilityElement = true
        button1.isAccessibilityElement = true
        button2.isAccessibilityElement = true
        parent.accessibilityLabel = "Message"
        self.view.addSubview(parent)
        self.view.accessibilityElements = [parent, button1, button2]
    }

    override func viewDidAppear(_ animated: Bool) {
    }
}

If there is a better way to get voiceover to give description of the view when the opens, I am open to that too.

Also, the view needs to be a modal so that focus is trapped on the view.



Solution 1:[1]

To achieve this I made the parent view to be an accessible element and the subviews which are two buttons are also accessible elements.

That's definitely the problem: you can't have the parent view and its children accessible all together ? see the example sheet of this explanation.
If a parent view is accessible, its children won't be seen by VoiceOver and conversely.

If there is a better way to get voiceover to give description of the view when the opens, I am open to that too.

Using VoiceOver, you must be as accurate and brief as possible.
The description of a view is provided by its elements when you explore the screen or by its title itself : in my view, you shouldn't read out a description that a perfect title should provide in addition to the correct implementation of the different components of your page.

There's a great presentation made by a blind person who explains how to write labels inside an app to be well understood.

Also, the view needs to be a modal so that focus is trapped on the view.

The best way to reach this purpose is to use the accessibilityViewIsModal property of your view ? take a look at this example introduced during a WWDC session if need be.

Solution 2:[2]

You can post a notification with a message as parameter, so you would not need to set the parent view as an accessibility element. This would solve both of your problems.

Example code:

    let parentVc = UIView()
    let button1 = UIButton()
    let button2 = UIButton()

    init() {

        parentVc.addSubview(button1)
        parentVc.addSubview(button2)
        button1.setTitle("btn1", for: .normal)
        button2.setTitle("btn2", for: .normal)

        button1.isAccessibilityElement = true
        button2.isAccessibilityElement = true

        self.view.addSubview(parentVc)
        self.view.accessibilityElements = [button1, button2]

        UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: "Message here");
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 alxlives