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.
CodePudding user response:
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.
CodePudding user response:
I've tried this in the past and had issues, I believe to do with contextMenu interaction on the actual collectionView.
You can fix it by putting the gesture handler on the collectionView itself and getting the gesture location, then cell at location as per this link;
how-to-make-tableviewcell-handle-both-tap-and-longpress
CodePudding user response:
only call setLongPress() in viewDidLoad()
func setLongPress(){
let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
lpgr.minimumPressDuration = 0.5
lpgr.delaysTouchesBegan = true
lpgr.delegate = self
self.CollectionView.addGestureRecognizer(lpgr)
}
@objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer?) {
if gestureRecognizer?.state != .ended {
return
}
let p = gestureRecognizer?.location(in: projectCollectionView)
let indexPath = CollectionView.indexPathForItem(at: p ?? CGPoint.zero)
if indexPath == nil {
print("couldn't find index path")
} else {
// get the cell at indexPath (the one you long pressed)
var cell: UICollectionViewCell? = nil
if let indexPath = indexPath {
// your action here
}
// do stuff with the cell
}
}
