Search code examples
iosswiftuicollectionviewcelluitapgesturerecognizer

UITapGestureRecognizer static method crashes


I have a swift app with multiple custom UICollectionViewCells. All of the cells have multiple objects (either UIImageView or UILabel) that the user can tap on (hence, I use multiple UITapGestureRecognizers to call the corresponding action. Now, to ease my job and make the code less repetitive, I wanted to create an extension of UITapGestureRecognizer with a static method that I can call directly on the class.

I did, but the fact that the app crashes means that there's something I didn't do well. Here's my code:

extension UITapGestureRecognizer {
    static func addNewTapGuestureRecognizer(for imageView: UIImageView, selectorName: Selector) {
        let tap = UITapGestureRecognizer(target: self, action: selectorName)
        imageView.addGestureRecognizer(tap)
        imageView.isUserInteractionEnabled = true
    }

    static func addNewTapGuestureRecognizer(for label: UILabel, selectorName: Selector) {
        let tap = UITapGestureRecognizer(target: self, action: selectorName)
        label.addGestureRecognizer(tap)
        label.isUserInteractionEnabled = true
    }
}

class TextCVC: UICollectionViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        addTapGuesturesForImagesAndLabels()
    }

    func addTapGuesturesForImagesAndLabels() {
        UITapGestureRecognizer.addNewTapGuestureRecognizer(for: postActionShareImageVIew, selectorName: #selector(self.shareImageTapped))
        UITapGestureRecognizer.addNewTapGuestureRecognizer(for: postActionLikeImageVIew, selectorName: #selector(self.likeImageTapped))
    }

    @objc func shareImageTapped() {
        print("share")
    }

    @objc func likeImageTapped() {
    }
}

The console error says:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[UITapGestureRecognizer likeImageTapped]: unrecognized selector sent to class 0x1b52e4c50'


Solution

  • The issue seems to be here : let tap = UITapGestureRecognizer(target: self, action: selectorName)

    The target is not self, it's the instance of the UICollectionViewCell.

    Change your code to :

    static func addNewTapGuestureRecognizer(for imageView: UIImageView, target: Any, selectorName: Selector) {
        let tap = UITapGestureRecognizer(target: target, action: selectorName)
        imageView.addGestureRecognizer(tap)
        imageView.isUserInteractionEnabled = true
    }