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?
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