Search code examples
iosswiftuicollectionviewuicollectionviewcell

UICollectionViewCell Deselect Pre-Selected Cell on First Tap


I am modally presenting a viewcontroller that hosts a viewcollection with "pre-selected" cells formatted to a different background color based on data passed on segue.

When I tap on one of these "pre-selected" cells, it takes two taps to trigger the didDeselectItemAt delegate method. I understand why this is happening while debugging, where the cell although of different color is not necessarily recognized in a selected state. Is there any way to trigger didDeselectItemAt first for the "pre-selected" cells?

I've tried, within the delegate method cellForItemAt, to incorporate, as part of a conditional statement that changes the cell background color, setting cell.isSelected = true. Similarly within the same delegate method, I've also tried invoking a function that would invoke the delegate method didSelectItemAt with indexPaths of these "pre-selected" cells. Both produced the same result.

Below is (abbreviated) relevant code snippets:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! ExampleCollectionViewCell

    if preselectedDataPoints { cell.backgroundColor = blue }
    else { cell.backgroundColor = white }
    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = blue
    preselectedDataPoints.append(newDataPoint)
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = white
    preselectedDataPoints.remove(at: existingDataPoint)
}

Solution

  • Programatically call collectionView.deselectItem(at: indexPath, animated: true) in didSelectItem if cell is preselected.

    Refrer code

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if preselectedDataPoints { 
           collectionView.deselectItem(at: indexPath, animated: true) 
        }else{
           let cell = collectionView.cellForItem(at: indexPath)
           cell?.backgroundColor = blue
           preselectedDataPoints.append(newDataPoint)
        }  
    
    }
    

    or

    Directly call what ever code you need to execute in deSelect method

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if preselectedDataPoints { 
           let cell = collectionView.cellForItem(at: indexPath)
           cell?.backgroundColor = white
           preselectedDataPoints.remove(at: existingDataPoint)
        }else{
           let cell = collectionView.cellForItem(at: indexPath)
           cell?.backgroundColor = blue
           preselectedDataPoints.append(newDataPoint)
        }  
    
    }