Tab Bar A11y trait and dataTable container type reads wrong number of tabs for collection views

Originator:christopher_hale
Number:rdar://FB9749029 Date Originated:9 Nov 2021
Status:Open Resolved:
Product:Accessibility Product Version:iOS 13-15
Classification: Reproducible:Yes
 
Both the UIAccessibilityTraits.tabBar and UIAccessibilityContainerType.dataTable APIs on UICollectionViews cause the wrong number of elements to be read by VoiceOver. This likely has something to do with UICollectionView's reused cells such that the view hierarchy is never the full number of elements. This is an issue at least as early as iOS 13.3 and at least as late as iOS 15.0.2.

For UIAccessibilityTraits.tabBar:
1. Create a collection view where the number of cells exceeds the width of the screen. Start with roughly double width.
2. Assign `collectionView.accessibilityTraits = [.tabBar]`
3. Open the app, then use the VO shortcut to turn it on while on the app is already opened and has rendered the collection view.
4. Go through each element on the screen. It should read "{Accessibility Label}, Tab, {x} of {y}" where y is the number of visible cells. When reaching the end of the visible cells and the collection view scrolls to accommodate, it changes its value of y. With long lists it sometimes changes the value of x as y also changes.

Expected: UICollectionView should automatically return the correct number of elements based on its data source.
Actual: UICollectionView appears to return the current number of subviews which can change when scrolling.

For UIAccessibilityContainerType.dataTable:
1. Create a collection view where the number of cells exceeds the width of the screen. Start with roughly double width.
2. Assign `collectionView.accessibilityContainerType = .dataTable` and also `collectionView.accessibilityTraits = [.tabBar]` to confirm behavior later.
3. Extend UICollectionView to implement the `UIAccessibilityContainerDataTable` protocol. On `accessibilityColumnCount()` and `accessibilityRowCount()` return the same number of sections and rows as the collection view data source would.
4. Open the app, then use the VO shortcut to turn it on while on the app is already opened and has rendered the collection view. Confirm that `accessibilityRowCount()` and `accessibilityColumnCount()` are being called.
5. Go through each element on the screen with VoiceOver. It should read "{Accessibility Label}, Spans {y} rows, Row {x}, Tab, {x} of {y}" where y is the number of visible cells. When reaching the end of the visible cells and the collection view scrolls to accommodate, it changes its value of y. With long lists it sometimes changes the value of x as y also changes. Note that the span and row counts correspond to the tab count.

Expected: The "Spans {y}, Row {x}" and "{x} of {y}" should use the values returned by the `UIAccessibilityContainerDataTable` protocol.
Actual: `UIAccessibilityContainerDataTable` protocol methods are being called but ignored when deriving the span/row/tab counts.

Notes:
 - These are not issues if we use, say, UIStackView within a UIScrollView.
 - Although sometimes having VO on before the launching the app fresh may cause the correct number of items to be read, as opposed to turning on VO after the views have rendered, this is not always the case.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!