I'm creating a custom UIControl
subclass, and want to add a addTarget()
function, similar to UIButton. How do I do this properly? So far I have this (it works, but not sure if is a good solution):
import UIKit
class RichLabel: UIControl {
var labelTarget: Any?
var labelAction: Selector?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func addTarget(_ target: Any?, action: Selector) {
self.labelTarget = target
self.labelAction = action
}
func buttonAction() {
if let labelTarget = labelTarget, let labelAction = labelAction {
let _ = (labelTarget as AnyObject).perform(labelAction, with: self)
}
}
The target is added from another view, like this:
var richLabel: RichLabel {
let label = RichLabel()
label.setAttributedText(title: string)
label.addTarget(self, action: #selector(richLabelAction(label:)))
return label
}
If you inherit from UIControl
, you don't need to do anything to addTarget
. Callers will use addTarget
on your custom UIControl the same way they would any other control. All your custom control has to do is decide when it wants to call those actions, and call sendActions(for:)
.
If your goal is to have this RichLabel
class function just like a button, I would add a UITapGestureRecognizer
to it, and in the gesture recognizer, call self.sendActions(for: .touchUpInside)
.
class RichLabel: UIControl {
override init(frame: CGRect) {
super.init(frame: frame)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(labelTapped))
addGestureRecognizer(tapGesture)
}
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func labelTapped() {
// When this happens, any object that called `addTarget`
// for the .touchUpInside event will get its callback triggered
sendActions(for: .touchUpInside)
}
}