Search code examples
iosswiftuicollectionviewuicollectionviewcell

Deselecting the cell in cellForItemAt when selecting cell in didSelectItemAt


I have a variabel selectedIndexPath, which gets the indexPath selected from previous view controller. I am getting the required backgroundColor for cell in the collection view of present view controller. But when I select another cell in the collection view, the selected cell of previous view controller remains same without being deselected. So, now I have two cells with the background color. Following is my code

var selectedIndexPath = IndexPath()

override func viewDidLoad() {
    super.viewDidLoad()
    self.collectionView.allowsMultipleSelection = false
    self.collectionView.allowsSelection = true
}

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

    if (indexPath == selectedIndexPath)
    {
        cell.backgroundColor = UIColor.white
    }
    else
    {
        cell.backgroundColor = UIColor.clear
    }

    collectionView.allowsMultipleSelection = false
    return cell
}


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.white
    collectionView.allowsMultipleSelection = false 
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath)
{
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.clear
    collectionView.allowsMultipleSelection = false
}

How do I deselect the cell in cellForItemAt, when I select new cell in didSelectItemAt. Thanks in advance.


Solution

  • First of all set allowsMultipleSelection in Interface Builder and remove all redundant occurrences of setting it in code

    You have to update the selectedIndexPath variable. Manipulating the cell directly is always a bad idea.
    Reloading the cells is much more reliable.

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
    {
        guard selectedIndexPath != indexPath else { return }
        let indexPathsToUpdate = [selectedIndexPath, indexPath]
        selectedIndexPath = indexPath            
        tableView.reloadRows(at: indexPathsToUpdate, with: .none)
    }
    
    
    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath)
    {
        guard selectedIndexPath == indexPath else { return }
        selectedIndexPath = IndexPath()
        tableView.reloadRows(at: [indexPath], with: .none)
    }
    

    There is only one problem: If you want to have an empty selection you have to declare selectedIndexPath as optional and handle it properly.