0

I was wondering, why UITapGestureRecognizer doesn't work, if we make it become the member variable of a class?

Not working. hideKeyboard is not called when tapped

class TabInfoSettingsCell: UICollectionViewCell {
    
    private let hideKeyboardTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))

    override func awakeFromNib() {
        super.awakeFromNib()
        
        self.isUserInteractionEnabled = true
        self.addGestureRecognizer(hideKeyboardTapGestureRecognizer)
    }

    @objc private func hideKeyboard() {
        print("hide keyboard")
    }

Working

class TabInfoSettingsCell: UICollectionViewCell {
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        self.isUserInteractionEnabled = true
        let hideKeyboardTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
        self.addGestureRecognizer(hideKeyboardTapGestureRecognizer)
    }

    @objc private func hideKeyboard() {
        print("hide keyboard")
    }

Do you have idea what is the reason behind, on why UITapGestureRecognizer does not work if we make it become the member variable of a class?

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • 2
    See [this](https://stackoverflow.com/questions/68205981/what-is-difference-of-self-in-lazy-var-and-varlet-block/68206356#68206356). `self` doesn't mean what you think it does when in a variable initialiser. – Sweeper Jul 08 '21 at 03:43
  • 1
    https://www.biteinteractive.com/rant-swift-cocoa-target-action/ – matt Jul 08 '21 at 04:35

1 Answers1

1

Property initializers are run before the class initializer. This means that self (the instance of the class in this case) is not available before class init (at the time of property initialization).

If you make it a lazy var instead, it will be executed later in the lifecycle after init has been run and it will work as expected.

Tarun Tyagi
  • 9,364
  • 2
  • 17
  • 30