ykay
ykay

Reputation: 1973

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.

Upvotes: 5

Views: 7700

Answers (3)

Aurelien
Aurelien

Reputation: 159

I found out that there was no need to subclass the UICollectionView. Instead, define the accessibility elements in the container view (the UITableViewCell) as follows:

accessibilityElements = [titleLabel, collectionView]

Now all the collectionView elements can be navigated.

Upvotes: 1

Vojta Rujbr
Vojta Rujbr

Reputation: 335

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.

Upvotes: 14

stevekohls
stevekohls

Reputation: 2255

You may want to try this:

let nextCell = collectionView.cellForItemAtIndexPath(nextIndexPath)
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification,
                                argument: nextCell)

in your onNextButtonTapped method, after your call to scrollToItemAtIndexPath.

This will focus Accessibility on the next collection view cell.

Upvotes: 0

Related Questions