Search code examples
uicollectionviewfocustvos

tvOS UICollectionViewFocusUpdateContext selects multiple items on fast scrolling


In my SpriteKit project I am using a UICollectionView to have a character select menu. Its a very simple CollectionView that has 8 cells in 1 row. Each cell only has an imageView of the character.

On tvOS I am not using the automatic/default focus system when I set

imageView.adjustsImageWhenAncestorFocused = true

because I do not like the shadow effect that I get with this.

So I am doing the focus stuff manually by using

func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {

    if let previousIndexPath = context.previouslyFocusedIndexPath, let cell = collectionView.cellForItem(at: previousIndexPath) {
        scaleDown(cell: cell, coordinator: coordinator)
    }

    if let nextIndexPath = context.nextFocusedIndexPath, let cell = collectionView.cellForItem(at: nextIndexPath) {
        scaleUp(cell: cell, coordinator: coordinator)
    }
}

ScaleUp and ScaleDown are 2 simple methods that will use the coordinator to animate the focus appearance of the cell. Nothing fancy going on here.

Everything is working great when I scroll slow to medium fast. However when I do a really fast scroll, where it goes basically from the 1st to the last cell, it sometimes selects multiple items. I end up with 2-3 cells in focus instead of just 1, it seems like the focus system cannot keep up.

Note: If I try to just change the scale of the imageView of the cell instead of the whole cell it seems much better, however I was still able to replicate the problem occasionally.

Is there anyway I can avoid this altogether?


Solution

  • Fixed it by changing the focus code to this

    func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
    
        if let previousCell = context.previouslyFocusedView as? UICollectionViewCell {
            scaleDown(cell: previousCell, coordinator: coordinator)
        }
    
        if let nextCell = context.nextFocusedView as? UICollectionViewCell {
            scaleUp(cell: nextCell, coordinator: coordinator)
        }
    }