我试图在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中声明它,所以怎么能我解决了这个问题?
答案 0 :(得分:9)
<强> 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)
}