iosswiftuicollectionviewuibuttonuiaction

UIAction calling multiple times when tapped on UIButton in CollectionViewCell


When I tap on button it will trigger multiple times.

CollectionViewCell file code

class PhotoCell: UICollectionViewCell {
    @IBOutlet weak var deleteButton: UIButton!
}

ViewController - cellforItemAt method implementation

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UICollectionViewCell() }

        let action = UIAction { _ in
            print("Delete button tapped!!!", indexPath.row)
        }

        cell.deleteButton.addAction(action, for: .touchUpInside)

        return cell
    }

If I configure UIButton addTarget then it work fine but I am not sure why it's not working with addAction.


Solution

  • One possible solution is to override prepareForReuse() in PhotoCell, as Johann mentioned.

    preparaForReuse() is use to Performs any clean up necessary to prepare the view for use again.

    We can remove all events from the button there!

    class PhotoCell: UICollectionViewCell {
        @IBOutlet weak var deleteButton: UIButton!
    
         override func prepareForReuse() {
            super.prepareForReuse()
            self.deleteButton.removeTarget(nil, action: nil, for: .allEvents)
        }
    
    }
    

    Add action in func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) like normally we do.

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UICollectionViewCell() }
            let action = UIAction { _ in
                print("Delete button tapped!!!", indexPath.row)
            }
            cell.deleteButton.addAction(action, for: .touchUpInside)
            return cell
        }