Bebhead
Bebhead

Reputation: 209

How to make UICollectionView only select a cell on touchup instead of touch down

Essentially what I have is a very simple UICollectionViewCell subclass which changes its background color and some other aesthetic characteristics with a property observer on its isSelected property:

class SelectableCell: UICollectionViewCell {

    override var isSelected: Bool{
        didSet{
            if(isSelected)
            {
                self.backgroundColor = UIColor.white
            }
            else
            {
                self.backgroundColor = UIColor.black
            }
        }
    }
}

This works more or less as intended, if I tap on one of these cells in my collection view, the background changes accordingly.

The problem is that if I select a cell, and then decide to scroll through my collection, the cell will de-select until I finish scrolling and then re-select

(NOTE: when I say re-select I don't mean that the delegate functions like didSelectItem are triggered - just that the isSelected property changes back to true)

This only seems to happen if I start my scroll within the bounds of another cell.

So what I'm assuming is happening is that it de-selects the cell immediately when I touch down, and when it detects that I'm scrolling instead of tapping it rolls the selection state back and re-selects the correct cell.

Is there some way I can have it only commit on touch up, or maybe keep it in a selected state for that intermediary period?

Upvotes: 4

Views: 1512

Answers (2)

Anton Filimonov
Anton Filimonov

Reputation: 1675

This is the way collection view handles the selection when only one cell could be selected at a time. One of the possible workarounds for you is to use multiple selection. In this case you'll have to manage the deselection of previously selected cell yourself. Like this:

// somewhere in viewDidLoad
collectionView.allowsMultipleSelection = true

//then in your delegate method
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let selectedIndexPaths = collectionView.indexPathsForSelectedItems else { return }

    for selectedIndexPath in selectedIndexPaths where selectedIndexPath != indexPath {
        collectionView.deselectItem(at: selectedIndexPath, animated: true)
    }
}

Upvotes: 3

Glenn Posadas
Glenn Posadas

Reputation: 13283

How to make UICollectionView only select a cell on touchup instead of touch down

Here's a quick solution, or idea rather. I haven't tried this yet, but I'm quite certain this would work:

  1. Add a clear button to your cell, occupying the edges of the cell.
  2. Add a selector, with event which you need, so in this case, a touch down if there's any.
  3. Then add a completion block or protocol to your cell to send the event to your controller.

Hope this helps!

Upvotes: 0

Related Questions