如何在另一个 class 中使用 addTarget 定位选择器

How do I targeting selector with addTarget in another class

我试图了解如何控制一个 class 到另一个 class 的组件,但这不起作用。

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")
    }
}

当我点击按钮时,没有任何反应!
我试着改变

button.addTarget(self, action: #selector(tapButton(_:)), for: .touchUpInside)

button.addTarget(nil, action: #selector(tapButton(_:)), for: .touchUpInside)

那是行不通的!

如何解决这个问题? 感谢您的帮助。

您有 3 个问题:

  1. instance 是一个局部变量,所以它会在 viewDidLoad() 完成后立即被释放。使其成为 VC 的 属性。该按钮仅保留对该对象的弱引用,因此当它被释放时它变为 nil。在目标为 nil 的情况下,UIKit 将在响应链中搜索操作方法。由于 VC 不提供 tapButton 方法,因此按下按钮时不会发生任何事情。
  2. 您需要调用 super.init() 以便 self 可以与按钮一起使用。 self 在所有属性都已初始化之前无法创建。因为 init 是一个 override,你必须先调用 super.init() 来初始化 NSObject 提供的属性,然后才能在按钮中使用 self
  3. 您的框架将您的按钮置于屏幕上无法访问的区域。我更改了你的框架,将按钮放在 iPhone 11 的安全区域内。我还制作了按钮 .green,以便我可以看到它。
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")
    }
}