Ios UIButton不在UIWindow的子视图上工作

Ios UIButton不在UIWindow的子视图上工作,ios,objective-c,swift,uibutton,Ios,Objective C,Swift,Uibutton,我正在尝试在Swift中创建一个自定义单按钮AlertViewController,我使用window.addSubview()显示AlertView,但当触摸AlertView上的按钮时,func buttonTapped()不起作用,下面是我的代码,请告诉我这里出了什么问题,谢谢 MyAlertViewController.swift class MyAlertViewController: UIViewController { var button: UIButton! v

我正在尝试在Swift中创建一个自定义单按钮AlertViewController,我使用window.addSubview()显示AlertView,但当触摸AlertView上的按钮时,func buttonTapped()不起作用,下面是我的代码,请告诉我这里出了什么问题,谢谢

MyAlertViewController.swift

class MyAlertViewController: UIViewController {
    var button: UIButton!
    var contentView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        setUp()
    }

    func setUp(){
        contentView = UIView(frame: CGRectMake(0,0,200,300))
        contentView.center = view.center
        contentView.backgroundColor = UIColor.whiteColor()
        contentView.layer.cornerRadius = 10

        button = UIButton(type: .System)
        button.frame = CGRectMake(50, 150, 100, 40)
        button.setTitle("button", forState: UIControlState.Normal)
        button.addTarget(self, action: #selector(buttonTapped(_:)), forControlEvents: UIControlEvents.TouchUpInside)

        view.addSubview(contentView)
        contentView.addSubview(button)
        view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.1)
        view.userInteractionEnabled = true
    }

    func buttonTapped(sender: AnyObject?){
        print("button tapped")
    }

    func show(){
        let window = UIApplication.sharedApplication().keyWindow! as UIWindow
        view.frame = window.bounds
        window.addSubview(view)
    }
}
ParentViewController.swift(是我的窗口的rootViewController)

我发现,如果按如下所示更改ParentViewController.swift,则警报视图上的按钮可以正常工作

class ParentViewController: UIViewController {
    var button: UIButton!
    var vc: MyAlertViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.cyanColor()
        button = UIButton(type: .System)
        button.frame = CGRectMake(110,269,100,30)
        button.setTitle("show", forState: .Normal)
        button.addTarget(self, action: #selector(buttonTapped(_:)), forControlEvents: .TouchUpInside)
        view.addSubview(button)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func buttonTapped(sender: AnyObject?){
        vc = MyAlertViewController()
        vc.show()
    }

}
但我打算在用户每次收到新消息时显示此警报视图,因此它将在任何时间和任何ViewController上显示,因此我不想在每个ViewController中声明它,因此我如何解决此问题?

TLDR

您必须保留MyAlertViewController()的一个实例

更改此选项,它将起作用(正如您已经做的那样):


更多解释

MyAlertViewController内部调用的
按钮.addTarget(self,…)
不会保留
self

addTarget
函数文档的最后一行说:

//。。。操作不能为NULL。请注意,不会保留目标*

因此,离开此功能后,将不会有
self
发送操作:

func buttonTapped(sender: AnyObject?){
    MyAlertViewController().show()
}

另一个选项, 在MyAlertViewController中保留
self
变量:

// retain self manually
var mySelf: MyAlertViewController?

func setUp(){
    ...
    // reference to self
    mySelf = self
    button.addTarget(mySelf, action: #selector(buttonTapped(_:)), forControlEvents: UIControlEvents.TouchUpInside)
}

谢谢,所以MyAlertViewController().show()没有创建对MyAlertViewController实例的强引用?@Keater是的。因此,行按钮。添加目标。。。基本上什么都不做。非常感谢。谢谢,它在类似的情况下帮助了我
func buttonTapped(sender: AnyObject?){
    MyAlertViewController().show()
}
// retain self manually
var mySelf: MyAlertViewController?

func setUp(){
    ...
    // reference to self
    mySelf = self
    button.addTarget(mySelf, action: #selector(buttonTapped(_:)), forControlEvents: UIControlEvents.TouchUpInside)
}