Search code examples
iosswiftuicollectionviewuicollectionviewcelluicolor

How do I return back to the first collectionview cell item?


I'm working in UICollectionViewCell for my mobile app. When you tap the crossBtn it should go to the first UICollectionViewCell with reloading the data but collectionView?.reloadData() makes the colours messed up and it doesn't stay to one colour at a time per cell. Instead it keeps showing multiple colours on the cells even though I've put the colour as UIColor.clear in didDeselectItemAt method.

How do I return back to the first UICollectionViewCell item when the user taps on crossBtn without reloading the whole UICollectionView?

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return filters.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell

        cell.hamburgerLabel.text = filters[indexPath.item]

//        cell.hamburgerImageView.image = filterImages[indexPath.item]

        return cell
    }


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.layer.backgroundColor = UIColor.gray.cgColor
    setFilter(title: filterNames[indexPath.row])
    toolBar.isHidden = true
    yesAndNoToolBar.isHidden = false
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.layer.backgroundColor = UIColor.clear.cgColor
    collectionView.deselectItem(at: indexPath, animated: true)
}


@IBAction func crossBtn(_ sender: UIBarButtonItem) {
    toolBar.isHidden = false
    yesAndNoToolBar.isHidden = true

    collectionView?.reloadData()

    let indexPath = self.collectionView.indexPathsForSelectedItems?.last ?? IndexPath(item: 0, section: 0)
    self.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: UICollectionViewScrollPosition.centeredVertically)

}

Solution

  • You may not have to reload the data. You can use the following method to scroll to a given index path.

    let indexPath = self.collectionView.indexPathsForSelectedItems?.last ?? IndexPath(item: 0, section: 0)
    func scrollToItem(at indexPath: indexPath, 
                   at scrollPosition: .centeredVertically, 
             animated: true)
    

    Note that this is different from using selectItem(at:animated:scrollPosition:).

    Also, you should set the colours etc that you are having trouble with in the cellForItem method, not in the selection and deselection delegate methods. This is because cells are reused, so the cell you are styling will be used in a different place when you scroll. Instead, use the selection and deselection methods to store the selected index path(s) in a variable (or array of multiple), then check this array in cellForItem to determine whether to apply selected styling to that cell. This is why collectionView.reloadData() messes things up for you!