1

I have the following code to initialize a label:

let forgotPasswordLabel: UILabel = {
        let label = UILabel()
        label.text = "Forgot password?"
        label.font = ApplicationScheme.instance.containerScheme.typographyScheme.subtitle1
        label.textColor = ApplicationScheme.instance.containerScheme.colorScheme.onPrimaryColor
        label.textAlignment = .right
        label.sizeToFit()
        label.accessibilityRespondsToUserInteraction = true
        label.isUserInteractionEnabled = true
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

And later on I add it to the subview as such:

let passwordLabel = forgotPasswordLabel
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onForgotPasswordClick))
passwordLabel.addGestureRecognizer(tapGesture)
self.view.addSubview(passwordLabel)

If I do the code as such then it works fine, however if I put the tapGesture code inside the label forgotPasswordLabel initialization, the tap gesture does not fire. Why is that?

Code that does not work:

let forgotPasswordLabel: UILabel = {
        let label = UILabel()
        label.text = "Forgot password?"
        label.font = ApplicationScheme.instance.containerScheme.typographyScheme.subtitle1
        label.textColor = ApplicationScheme.instance.containerScheme.colorScheme.onPrimaryColor
        label.textAlignment = .right
        label.sizeToFit()
        label.isUserInteractionEnabled = true
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onForgotPasswordClick))
        label.addGestureRecognizer(tapGesture)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

Does this have something to do with the garbage collector? Unrecognized bounds for the UILabel? Or something else?

Mayank
  • 315
  • 2
  • 13
uioporqwerty
  • 1,068
  • 3
  • 12
  • 30

1 Answers1

1

The tapGesture in following code is added inside the Closure initializer, and with that you assign target as self which is not valid. Coz self here is not the ViewController

let forgotPasswordLabel: UILabel = {
        let label = UILabel()
        label.text = "Forgot password?"
        label.font = ApplicationScheme.instance.containerScheme.typographyScheme.subtitle1
        label.textColor = ApplicationScheme.instance.containerScheme.colorScheme.onPrimaryColor
        label.textAlignment = .right
        label.sizeToFit()
        label.isUserInteractionEnabled = true
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onForgotPasswordClick))
        label.addGestureRecognizer(tapGesture)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

Where as in the following code where the tapGesture is working as expected you are setting target as self which is the ViewController and that is valid.

let forgotPasswordLabel: UILabel = {
    let label = UILabel()
    label.text = "Forgot password?"
    label.font = ApplicationScheme.instance.containerScheme.typographyScheme.subtitle1
    label.textColor = ApplicationScheme.instance.containerScheme.colorScheme.onPrimaryColor
    label.textAlignment = .right
    label.sizeToFit()
    label.accessibilityRespondsToUserInteraction = true
    label.isUserInteractionEnabled = true
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

let passwordLabel = forgotPasswordLabel
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onForgotPasswordClick))
passwordLabel.addGestureRecognizer(tapGesture)
self.view.addSubview(passwordLabel)

In case of tapGesture when you set the target it tells that where to look for the action when the gesture happens

Harshal Bhavsar
  • 1,598
  • 15
  • 35