Search code examples
swiftuitapgesturerecognizer

UITapGestureRecognizer not attaching action


I created a separate class for View. I left all the functions in the Controller. But when I add a click on the picture, it doesn't work for some reason.

import UIKit

class APOTDView: UIView {

    var imageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: self, action: #selector(APOTDViewController.imageTapped(_:)))
        imageView.addGestureRecognizer(tap)

        return imageView
    }()
}
import UIKit

class APOTDViewController: UIViewController {

    let av = APOTDView()

    override func viewDidLoad() {
        super.viewDidLoad()
        // ... add subview and constraint
    }

    @objc func imageTapped(_ sender: UITapGestureRecognizer) {
        print("good job")
    }
}

What's the matter? Please help me figure it out


Solution

  • Your selector in the UITapGestureRecognizer is wrong. You can not call the APOTDViewController directly.
    APOTDViewController.imageTapped would be a static function, which is not available.

    You can use a delegate instead.

    Delegate Protocol and View.

    protocol APOTDViewDelegate: AnyObject {
        func viewDidTapImage()
    }
    
    class APOTDView: UIView {
        weak var delegate: APOTDViewDelegate?
    
        var imageView: UIImageView = {
            let imageView = UIImageView()
            imageView.translatesAutoresizingMaskIntoConstraints = false
            imageView.isUserInteractionEnabled = true
            let tap = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
            imageView.addGestureRecognizer(tap)
    
            return imageView
        }()
    
        @objc func imageTapped() {
            delegate?.viewDidTapImage()
        }
    }
    

    ViewController:

    class APOTDViewController: UIViewController, APOTDViewDelegate {
        let av = APOTDView()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            av.delegate = self
            // ... add subview and constraint
        }
    
        @objc func viewDidTapImage() {
            print("good job")
        }
    }