Reputation: 2211
Presently, I have a container view holding a UICollectionView, which has a number of accessibility-enabled cells.
While using VoiceOver, I can cycle through all the elements in the app, and when I get to my container view, it will cycle through all the cells and their labels (I don't have any accessibility methods or properties enabled on my container view).
However, I'd like it so that I can assign an accessibility label to the UICollectionView so that VO reads the UICollectionView's accessibility label FIRST, before it reads the first cell's accessibility label.
ie, Button immediately above CollectionView's label: "Button" CollectionView's label: "Filter Bar" Cell 1's (default selected) label: "Sports" Cell 2's label: "Chevrolet"
Scenario: When the user has Button selected, and swipes to the right, the first cell in the table view gets selected.
Expected Result: VO reads: "Filter Bar, selected, Sports, button"
Actual Result: VO reads: "selected, Sports, button".
Is it possible to make VO read the accessibility label of the collection view first?
Upvotes: 1
Views: 4464
Reputation: 5671
A UICollectionView
may be seen as a container inside which many elements are embedded (its cells) and, as is, you can't have simultaneously a parent view (the collection view) and its child views (its cells) that are both accessible with VoiceOver: either the collection view can be selected or its cells.
Is it possible to make VO read the accessibility label of the collection view first?
Following the explanation above, you can't with the present configuration.
However, a solution may be to create a UIAccessbilityElement
that wraps your collection view with the simple label you want to be read out: this element will be selected before the collection view cells are in turn.
Finally, I strongly recommend to take a look at the demo inside this detailed WWDC video that may provide some useful tips for your use case.
⚠️ ⬛️◼️🔳▪️ EDIT ▪️🔳◼️⬛️ ⚠️ (after MarkS's comments)
I'm trying to figure out a way to wrap it, but so far I've been unsuccessful.
Try this code snippet hereafter to create your accessibility element:
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let a11yWrapper = UIAccessibilityElement(accessibilityContainer: view!)
a11yWrapper.accessibilityFrameInContainerSpace = CGRect.init(x: 40.0,
y: 40.0,
width: 100.0,
height: 50.0)
a11yWrapper.accessibilityLabel = "Filter Bar"
a11yWrapper.accessibilityTraits = .staticText
view.accessibilityElements = [a11yWrapper]
}
}
Adapt it to your app environment and that should make VO read the accessibility label of the collection view first.
There aren't any examples in the documentation which specifically go over this situation.
I think it's because your design shouldn't be done this way.
Usually, it's either the collection view itself or its cells that are accessible, not both as explained earlier.
However, according to what you exposed in your post, you could use the custom actions to reach your purpose as well: each action will correspond to a particular cell... that's definitely not perfect but that's as close as you can get to what you’re asking.
Upvotes: 0