简体   繁体   English

UIButton没有在UIWindow的子视图上工作

[英]UIButton not working on a subview of UIWindow

I'm trying to create a custom one-button AlertViewController in Swift, I use window.addSubview() to show the AlertView, but when touch the button on the AlertView, the func buttonTapped() is not working, below is my code, please tell me what's wrong here, thanks. 我正在尝试在Swift中创建一个自定义的一键AlertViewController,我使用window.addSubview()来显示AlertView,但是当触摸AlertView上的按钮时,func buttonTapped()不起作用,下面是我的代码,请告诉我这里有什么问题,谢谢。

MyAlertViewController.swift 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 (is the rootViewController of my window) ParentViewController.swift(是我窗口的rootViewController)

class ParentViewController: UIViewController {
    var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.whiteColor()
        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?){
        MyAlertViewController().show()
    }

}

在此输入图像描述

I found out if I change ParentViewController.swift as below, the button on the alert view can work correctly. 我发现如果我更改下面的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()
    }

}

But I intended to show this alert view each time the user get new messages,so it would show up at any time and on any ViewController , so I don't want to declare it in each ViewController, so How can I solve this? 但我打算每次用户收到新消息时显示此警报视图,因此它会随时显示在任何ViewController上,所以我不想在每个ViewController中声明它,所以我该如何解决这个问题呢?

TLDR ; TLDR ;

You have to retain an instance of MyAlertViewController(). 您必须保留 MyAlertViewController()的实例。

Change to this and it will work (as you've already done): 更改为此并且它将起作用(正如您已经完成的那样):

// keep some reference
var alert: MyAlertViewController?

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

More explanation 更多解释

The button.addTarget(self, ...) that is called inside MyAlertViewController does not retain self . button.addTarget(self, ...) 不会保留self

The last line of the doc of addTarget function said that: addTarget函数doc的最后一行说:

// ... the action cannot be NULL. // ...动作不能为NULL。 Note that the target is not retained.* 请注意,目标不会被保留。*

So there will be no self to send action to after leaving of this function: 因此,在离开此功能后将没有self发送动作:

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

Another option , is to keep self variable in MyAlertViewController: 另一个选择是在MyAlertViewController中保持self变量:

// retain self manually
var mySelf: MyAlertViewController?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM