Charlie S
Charlie S

Reputation: 4594

Unable to shift voiceover focus to a specific UICollectionView cell

I am using the following tried and tested code to get VoiceOver to select a certain UICollectionViewCell:

var indexPath = IndexPath(row: 4, section: 3)
if let cell = self.collectionView.cellForItem(at: indexPath) {
      UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged,
                                     argument: cell)
}

However, whatever cell I set the index path to, VoiceOver ignores this and always ends up selecting the last selected UICollectionViewCell. Even if I deselect that cell beforehand using:

self.collectionView.selectItem(at: nil, animated: false, scrollPosition: .bottom)

Question 1. Has anyone come across this issue? 2. Is this another VoiceOver bug? 3. Does anyone have a workaround for it?

Upvotes: 2

Views: 1843

Answers (1)

Thisura Dodangoda
Thisura Dodangoda

Reputation: 741

First, make sure your cells have accessibility enabled and that they have a valid accessibility label.

As a test implementation, I added the following code in the UICollectionViewDataSource's cellForItemAt method.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kCellIdentifier, for: indexPath)
    
    let numberOfCells = 100
    
    // Set these values if you haven't
    cell.isAccessibilityElement = true
    cell.accessibilityLabel = "Cell \(indexPath.item) of \(numberOfCells))"
    
    return cell
}

Note: I got into trouble when the collectionView also had accessibility enabled. VoiceOver worked fine when only the cells had accessibility enabled.

Next, try calling your initial methods to get VoiceOver to select the collection view cell. I got some additional smoothness by first selecting the cell from the collectionView's selectItem method as shown below.

var indexPath = IndexPath(row: 4, section: 3)
if let cell = self.collectionView.cellForItem(at: indexPath) {
    self.collectionView.selectItem(
        at: indexPath,
        animated: true,
        scrollPosition: [.centeredVertically, .centeredHorizontally]
    )
    UIAccessibility.post(
        notification: UIAccessibility.Notification.screenChanged,
        argument: cell
    )
}

Upvotes: 1

Related Questions