Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionView in a UITableViewCell with Accessibility

I'm adding Accessibility support to my iOS app and I'm having trouble with a collection view in one of my table view cells.

For example, when the user scrolls (horizontally) from the first cell to the second cell, Accessibility still reads the contents of the first cell. If I try to tap on a view in the second cell, it highlights an empty space to the left of the second cell (where the first cell would be but no longer visible) and reads the contents of the first cell.

When the collection view is not in a table view cell (i.e. a subview of a UIView), this does not happen.

I'm suspecting this has something to do with calling UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification) and I've tried calling it in many different places, but nothing has worked.

The following two screenshots show a collection view inside a UIView. Accessibility is enabled, so it gets selected with a black border when tapped.

  1. When user taps first cell, it will get selected.

  1. When the user taps 'Next', goes to the second cell, and taps the cell, the new cell will get selected.

The next two screenshots show the collection view inside a table view cell.

When the user taps the first cell, it gets selected and VoiceOver properly reads "I'm label 0".

However, when the user taps 'Next', goes to the next cell, and taps the second cell, it does not get selected and VoiceOver will still read, "I'm label 0".

The code is available here on github.

like image 557
ykay Avatar asked Aug 08 '16 01:08

ykay


People also ask

What is the difference between Uitableview and UICollectionView?

Tableiw is a simple list, which displays single-dimensional rows of data. It's smooth because of cell reuse and other magic. 2. UICollectionView is the model for displaying multidimensional data .

How is UICollectionView implemented?

Create a new iOS app project Add a CollectionView by pressing command shift L to open the storyboard widget window. Drag the collectionView onto the main view controller. Add constraints to the UICollectionView widget to ensure that the widget fills the screen on all devices.

How do I stop auto scrolling of UICollectionView by voiceover?

UIScrollViewDelegate. scrollViewDidScroll(_:) A change in the accessibility focus that triggers an automatic scrolling also triggers a call to scrollViewDidScroll(_:) in your UIScrollViewDelegate. Use that to counter the automatic scrolling effect, f.i. by setting contentOffset the way you prefer it.

What is a UICollectionView?

An object that manages an ordered collection of data items and presents them using customizable layouts.


1 Answers

I had simillar problem which I eventually resolved. I think that you have mismatched elements with

isAccessibilityElement = true 

over each other.

I have a table view which scrolls vertically and each cell contains a title and collection view which scrolls horizontally.

I set isAccessibilityElement to true only on title and collection view cells, false on the rest.

Then, I subclassed UICollectionView and overrode the following NSObject methods:

func accessibilityElementCount() ->  Int
func accessibilityElement(at: Int) -> Any?
func index(ofAccessibilityElement element: Any) -> Int

It basically just tells the voice over that your collection view has these accessible elements. The collection view itself is not accessible which is not a problem, the contrary. You could probably use

open var accessibilityElements: [Any]?

instead.

Here is some more reading from documentation (UIAccessibility.h):

UIAccessibilityContainer methods can be overridden to vend individual elements that are managed by a single UIView.

For example, a single UIView might draw several items that (to an end user) have separate meaning and functionality. It is important to vend each item as an individual accessibility element.

Sub-elements of a container that are not represented by concrete UIView instances (perhaps painted text or icons) can be represented using instances of UIAccessibilityElement class (see UIAccessibilityElement.h).

Accessibility containers MUST return NO to -isAccessibilityElement.

To allow nice 3-finger voice over scroll you probably want to override

func accessibilityScroll(_ direction: UIAccessibilityScrollDirection) -> Bool

as well and scroll your collection view accordingly.

like image 53
Vojta Rujbr Avatar answered Oct 12 '22 23:10

Vojta Rujbr