Ios Can';不能在另一个类中设置UIButton目标?

Ios Can';不能在另一个类中设置UIButton目标?,ios,swift,uibutton,uikit,Ios,Swift,Uibutton,Uikit,我正在尝试构建一个自定义控制器来管理一组UIButton 设置和放置按钮的ViewController: override func viewDidLoad() { super.viewDidLoad() let button1 = UIButton() button1.setTitle("Button 1", for: UIControlState.normal) button1.setTitleColor(UIColor.blue, for: UIContr

我正在尝试构建一个自定义控制器来管理一组UIButton

设置和放置按钮的ViewController:

override func viewDidLoad() {
    super.viewDidLoad()

    let button1 = UIButton()
    button1.setTitle("Button 1", for: UIControlState.normal)
    button1.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button1.frame.origin.y = 120
    button1.sizeToFit()
    button1.isUserInteractionEnabled = true

    let button2 = UIButton()
    button2.setTitle("Button 2", for: UIControlState.normal)
    button2.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button2.frame.origin.y = 160
    button2.sizeToFit()


    let button3 = UIButton()
    button3.setTitle("Button 3", for: UIControlState.normal)
    button3.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button3.frame.origin.y = 190
    button3.sizeToFit()

    let controller = CustomButtonController(buttons: button1, button2, button3)

    self.view.addSubview(button1)
    self.view.addSubview(button2)
    self.view.addSubview(button3) }
CustomButtonController:

class CustomButtonController : NSObject {
    init(buttons: UIButton...) {
        super.init()
        for aButton in buttons {
            aButton.addTarget(self, action: #selector(pressed(_:)), for: UIControlEvents.touchUpInside)
        }
    }

    func pressed(_ sender: UIButton) {
        print("Press received in CustomButtonController")
        //Never gets called
    }
}

如果我在ViewController内部的按钮上使用addTarget方法,那么它可以正常工作。你知道为什么我们不能把目标添加到这样一个按钮上吗?谢谢

您正在
viewDidLoad
中将
CustomButtonController
创建为本地常量。只要
viewDidLoad
返回,该对象就会被释放,因此不再处理按钮点击

您需要声明实例属性以保存控制器实例:

var controller: CustomButtonController!

override func viewDidLoad() {
    super.viewDidLoad()

    let button1 = UIButton()
    button1.setTitle("Button 1", for: UIControlState.normal)
    button1.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button1.frame.origin.y = 120
    button1.sizeToFit()
    button1.isUserInteractionEnabled = true

    let button2 = UIButton()
    button2.setTitle("Button 2", for: UIControlState.normal)
    button2.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button2.frame.origin.y = 160
    button2.sizeToFit()


    let button3 = UIButton()
    button3.setTitle("Button 3", for: UIControlState.normal)
    button3.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button3.frame.origin.y = 190
    button3.sizeToFit()

    controller = CustomButtonController(buttons: button1, button2, button3)

    self.view.addSubview(button1)
    self.view.addSubview(button2)
    self.view.addSubview(button3) 
}

您正在将
CustomButtonController
创建为
viewDidLoad
中的本地常量。只要
viewDidLoad
返回,该对象就会被释放,因此不再处理按钮点击

您需要声明实例属性以保存控制器实例:

var controller: CustomButtonController!

override func viewDidLoad() {
    super.viewDidLoad()

    let button1 = UIButton()
    button1.setTitle("Button 1", for: UIControlState.normal)
    button1.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button1.frame.origin.y = 120
    button1.sizeToFit()
    button1.isUserInteractionEnabled = true

    let button2 = UIButton()
    button2.setTitle("Button 2", for: UIControlState.normal)
    button2.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button2.frame.origin.y = 160
    button2.sizeToFit()


    let button3 = UIButton()
    button3.setTitle("Button 3", for: UIControlState.normal)
    button3.setTitleColor(UIColor.blue, for: UIControlState.normal)
    button3.frame.origin.y = 190
    button3.sizeToFit()

    controller = CustomButtonController(buttons: button1, button2, button3)

    self.view.addSubview(button1)
    self.view.addSubview(button2)
    self.view.addSubview(button3) 
}

吸引我眼球的是子类化NSObject。根据情况,我倾向于用两种不同的方式来做。(1) 如果我想创建一个按钮并在其init上添加一个目标,我会创建一个方便的初始值设定项并传入目标和选择器。(2) 如果我想传递一个按钮被按下的事实,我不会(a)标记它,(b)使用按钮的.sendAction。也许这些方法中的一种对你有用。魔鬼就在细节中。您需要显示调用此函数的调用的特定序列。哪个对象正在创建谁?谁打电话给CustomButtonController?我猜您是在视图控制器的视图加载之前调用CustomButtonController。@Duncac add init code,不要认为button init有任何问题。对象初始化并传递良好,CustomButtonController在每个按钮上运行addTarget()。它只是没有调用选择器。吸引我注意的是子类化NSObject。根据情况,我倾向于用两种不同的方式来做。(1) 如果我想创建一个按钮并在其init上添加一个目标,我会创建一个方便的初始值设定项并传入目标和选择器。(2) 如果我想传递一个按钮被按下的事实,我不会(a)标记它,(b)使用按钮的.sendAction。也许这些方法中的一种对你有用。魔鬼就在细节中。您需要显示调用此函数的调用的特定序列。哪个对象正在创建谁?谁打电话给CustomButtonController?我猜您是在视图控制器的视图加载之前调用CustomButtonController。@Duncac add init code,不要认为button init有任何问题。对象初始化并传递良好,CustomButtonController在每个按钮上运行addTarget()。只是没有打电话给选择器。是的,我正要说同样的话,但你抢先一步。(投票)如果你不保持对你的
CustomButtonController
的强烈引用,它将被释放。是的,我正要说同样的话,但你抢先一步。(投票)如果您不保留对
CustomButtonController
的强引用,它将被取消分配。