Nish
Nish

Reputation: 193

didSelectItemAt and didDeselectItemAt are not working as expected in swift 3.0

I am using didSelectItemAt and didDeselectItemAt for multiple selection of collectionViewCell. I want to select the cell and make the border blue color if it is selected and also unselect the 'selected' cell and make the border default. But my problem is that didDeselectItemAt is getting called alternately. when once i tap on any cell then didSelectItemAt is called and if i tap on any other cell then didDeselectItemAt is called. This should not happen i guess. didDeselectItemAt should be called only if i am tapping on already selected cell. Please correct me if i am going wrong. I have refered this UICollectionView - didDeselectItemAtIndexPath not called if cell is selected1 but dint work for me :(

public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
   let cell = collectionView.cellForItem(at: indexPath) as!  MomentDetailCell
   let moment = self.arrOfMoments[indexPath.row] as! MomentModel
   cell.toggleSelection(moment: moment)
   self.arrOfDeletingImgs.append(moment) 
}

public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath)
{
   let cell : MomentDetailCell = self.collectionViewImages.cellForItem(at: indexPath) as! MomentDetailCell
   let moment = self.arrOfMoments[indexPath.row] as! MomentModel
   cell.toggleSelection(moment: moment)
   self.arrOfDeletingImgs.remove(at: (find(objecToFind: moment))!)
}

// Also this is the code i am using in the class. I have also made allowsMultipleSelection true in viewdidload

 extension MomentDetailViewController : UICollectionViewDelegateFlowLayout
{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
    {
      return CGSize(width: 75, height: 75)
    }
}

// This is my customCell code

func toggleSelection( moment : MomentModel)
{
    if (isSelected)
    {
        moment.isSelected = true
        self.layer.borderWidth = 3
        self.layer.borderColor = Constant.APP_BLUE_COLOR.cgColor

    }
    else
    {
        moment.isSelected = false
        self.layer.borderWidth = 1
        self.layer.borderColor = UIColor.red.cgColor
    }
}

Upvotes: 2

Views: 5899

Answers (4)

Lord Fresh
Lord Fresh

Reputation: 636

In my case i had a separate delegate class, and if i set collectionView.delegate = MyDelegate(), it didnt work, if i stored a var myDelegate = MyDelegate()in my viewcontroller and then set collectionView.delegate = myDelegate it somehow worked.

Upvotes: 0

Nish
Nish

Reputation: 193

After long time i troubleshooted the problem and this is what worked for me...

I was doing following thing in cellForItemAtIndexPath: which is WRONG

cell.isSelected = false
collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .left)

I was doing this as didDeselect was getting called alternately without considering the selection of cell. I just uncommeted this code and it worked for me. Now didSelect is calling on first click and if i click on same cell again then only didDeselect is called as per expected flow.

Also make sure allowsMultipleSelection is true and also allowsSelection is true

Upvotes: 4

Son Pham
Son Pham

Reputation: 1634

I guess didselect method is called when you tap on second cell. Might be you forgot:

_collectionView.allowsMultipleSelection = YES

Upvotes: 2

KKRocks
KKRocks

Reputation: 8322

Try this :

This solution for multiple selection

1- make deSelect as below

 public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
    {
       let cell = collectionView.cellForItem(at: indexPath) as!  MomentDetailCell
       let moment = self.arrOfMoments[indexPath.row] as! MomentModel
       cell.toggleSelection(moment: moment)
       self.arrOfDeletingImgs.append(moment) 
    }

2 - Comment/Remove Deselect method

3 change in this method

func toggleSelection( moment : MomentModel)
{
   moment.isSelected = !moment.isSelected
   self.layer.borderWidth =  moment.isSelected ? 3 : 1
   self.layer.borderColor =  moment.isSelected ?  Constant.APP_BLUE_COLOR.cgColor :  UIColor.red.cgColor

}

Upvotes: 4

Related Questions