swiftuicollectionviewcellgestureuilongpressgesturerecogni

Adding UILongPressGesture to Cell not CollectionView


I am trying to add UILongGestureRecognizer to my Custom CollectionView Cell but handler function never called. This is my gesture and handlerFunc from custom cell:

let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))

@objc func handleLongPress(_ recognizer: UILongPressGestureRecognizer) {
    switch recognizer.state {
    case .possible:
        break
    case .began:
        print("began")
        break
    case .changed:
        break
    case .ended:
        print("ended")
        break
    case .cancelled:
        break
    case .failed:
        break
    @unknown default:
        break
    }
}

Also, this is my cell configure function:

func configure(with viewModel: RecordsCollectionViewCellViewModel, itemCount: Int) {
    longPress.numberOfTapsRequired = 1
    longPress.minimumPressDuration = 0.3
    longPress.delaysTouchesBegan = true
    longPress.delegate = self
    
    self.bringSubviewToFront(gestureView)
    gestureView.isUserInteractionEnabled = true
    gestureView.addGestureRecognizer(longPress)

}

The gestureView is the transparent view at the top of the cell.


Solution

  • If you are looking for the best solution, I think there are better solutions such as adding the UILongPressGestureRecognizer to the collection view and figuring out which cell was tapped or if you need to present some options on long tap func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath and reason they are recommended because there is already some gesture management on the collection view.

    However, if you have considered all of this and still feel your solution is the right one for you, I think the issue is with this line let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:))) which seems to be initialized by default along with a cell.

    I feel maybe when the cell is getting reused, something is not getting configured right in func configure

    I would do these changes:

    func configure(with viewModel: RecordsCollectionViewCellViewModel, itemCount: Int) {
    
            // Remove any previous gesture recognizers, maybe this is not needed 
            gestureView.gestureRecognizers?.removeAll()
    
            // Initialize a new gesture recognizer
            let longPress = UILongPressGestureRecognizer(target: self,
                                                         action: #selector(handleLongPress))
            
            // longPress.numberOfTapsRequired = 1 - not needed
            
            longPress.minimumPressDuration = 0.3
            
            // longPress.delaysTouchesBegan = true - not needed
            
            // longPress.delegate = self - not needed unless you are doing something else
            
            gestureView.isUserInteractionEnabled = true
            
            gestureView.addGestureRecognizer(longPress)
    }
    

    Give this a try and see now if you function handleLongPress is being called ? On my end this works.