Search code examples
iosuiscrollviewuicollectionviewuitapgesturerecognizeruikeyboard

collectionView's didSelectItemAt not called when use it with UITapGestureRecognizer


Once I use addGestureRecognizer to dismiss keyboard in scrollView, collectionView's didSelectItemAt would not work. Any suggestions?

UPDATE CODE: Currently I can tap to dismiss keyboard and tap to do something with collection cell. But, if I swipe the scrollView, the keyboard will dismiss. Any way to prevent that?

class PostVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    @IBOutlet weak var colorCollectionView: UICollectionView!
    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var titleTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapViewGesture = UITapGestureRecognizer(target: self, action: #selector(PostVC.didTapViewForDismissKeyboard))
        scrollView.addGestureRecognizer(tapViewGesture)
        tapViewGesture.delegate = self
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool{
        view.endEditing(true)
        return false
    }

    func didTapViewForDismissKeyboard(_ pressed: UIGestureRecognizer) {
        view.endEditing(true)
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("HIHI")
    }

extension PostVC: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

Solution

  • Try to implement UIGestureRecognizerDelegate. Implement its gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) method in your code to return true - that way your gesture recognizer will work, but it will also allow other gestures to be recognized (specifically the one in the collectionView).

    Code:

    // add this to initializing code to set gesture recognizer's delegate to self
    tapViewGesture.delegate = self
    

    Delegate implementation:

    extension YourViewController: UIGestureRecognizerDelegate {
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    }