【问题标题】:UIButton not working on a subview of UIWindowUIButton 在 UIWindow 的子视图上不起作用
【发布时间】:2016-08-05 17:47:30
【问题描述】:

我正在尝试在 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)

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

}

我发现如果我更改 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 中声明它,所以我该如何解决这个?

【问题讨论】:

    标签: ios objective-c swift uibutton


    【解决方案1】:

    TLDR;

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

    改成这个,它会起作用(就像你已经做的那样):

    // keep some reference
    var alert: MyAlertViewController?
    
    func buttonTapped(sender: AnyObject?){
        alert = MyAlertViewController()
        alert?.show()
    }
    

    更多解释

    在 MyAlertViewController 中调用的button.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 是的。所以这行 button.addTarget... 基本上什么都不做。
    • 非常感谢.. .
    • 谢谢,它在类似的情况下帮助了我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多