Reputation: 467
I try to understand how to control component form one class to another class but that's not working.
class VC:UIViewController {
override func viewDidLoad() {
let instance = Test()
self.view.addSubView(instance.button)
}
}
class Test:NSObject {
var button:UIButton!
override init() {
button = UIButton(frame:CGRect(x:0, y:0, width:100, height:40))
button.setTitle(("TEST", for:.normal)
button.addTarget(self, action: #selector(tapButton(_:)), for: .touchUpInside)
}
@objc func tapButton(_ sender:UIButton) {
print("TAP Button")
}
}
When I tapped the button, nothing happens !
I try to change
button.addTarget(self, action: #selector(tapButton(_:)), for: .touchUpInside)
with
button.addTarget(nil, action: #selector(tapButton(_:)), for: .touchUpInside)
That's not working !
How to resolve this problem ? Thanks for your help.
Upvotes: 0
Views: 1010
Reputation: 154523
You have 3 issues:
instance
is a local variable, so it gets deallocated as soon as viewDidLoad()
finishes. Make it a property of VC
. The button only keeps a weak reference to the object, so when it is deallocated it becomes nil
. In cases where the target is nil
, UIKit will search up the responder chain for the action method. Since VC
doesn't supply a tapButton
method, nothing happens when the button is pressed.super.init()
so that self
is available to be used with the button. self
can't be created until all properties have been initialized. Because init
is an override
, you must call super.init()
to initialize the properties that NSObject
provides before you can use self
in the button..green
so that I could see it.class VC: UIViewController {
var instance = Test() // make instance a property
override func viewDidLoad() {
// let instance = Test() // this was a local variable that doesn't hang around
self.view.addSubview(instance.button)
}
}
class Test: NSObject {
var button: UIButton!
override init() {
super.init() // call this so that you can use self below
button = UIButton(frame:CGRect(x: 100, y: 100, width: 100, height: 40))
button.setTitle("TEST", for:.normal)
button.backgroundColor = .green
button.addTarget(self, action: #selector(tapButton(_:)), for: .touchUpInside)
}
@objc func tapButton(_ sender: UIButton) {
print("TAP Button")
}
// Add deinit to see when this object is deinitialized. When
// instance is local to viewDidLoad() this object gets freed
// when viewDidLoad() finishes.
deinit {
print("Oops, the Test object has been deinitialized")
}
}
Upvotes: 3