AlertController不在窗口层次结构中

我刚刚创build了一个ViewController类的单一视图应用程序项目。 我想从位于我自己的类中的函数显示一个UIAlertController。

这是我的class级警报。

class AlertController: UIViewController { func showAlert() { var alert = UIAlertController(title: "abc", message: "def", preferredStyle: .Alert) self.presentViewController(alert, animated: true, completion: nil) } } 

这是执行警报的ViewController。

 class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func showAlertButton(sender: AnyObject) { var alert = AlertController() alert.showAlert() } } 

这是我得到的,而不是美丽的戒备。

警告:尝试在Sprint1.AlertController上显示UIAlertController:0x797d2d20:0x797cc500其视图不在窗口层次结构中!

我该怎么办?

我们来看看你的视图层次结构。 你有一个ViewController 。 然后你创build一个AlertController ,你没有把它添加到你的层次结构中,并且你正在调用一个实例方法,试图使用AlertController作为呈现控制器来显示另一个控制器( UIAlertController )。

 + ViewController + AlertController (not in hierarchy) + UIAlertController (cannot be presented from AlertController) 

简化您的代码

 class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func showAlertButton(sender: AnyObject) { var alert = UIAlertController(title: "abc", message: "def", preferredStyle: .Alert) self.presentViewController(alert, animated: true, completion: nil) } } 

这将工作。

如果您需要某种AlertController ,则必须先将其添加到层次结构中,例如使用addChildViewController或使用另一个presentViewController调用。

如果你想让这个类只是帮助创build警报,它应该是这样的:

 class AlertHelper { func showAlert(fromController controller: UIViewController) { var alert = UIAlertController(title: "abc", message: "def", preferredStyle: .Alert) controller.presentViewController(alert, animated: true, completion: nil) } } 

称为

  var alert = AlertHelper() alert.showAlert(fromController: self) 

如果你从模态控制器实例化你的UIAlertController ,你需要在viewDidAppear ,而不是在viewDidLoad否则你会得到一个错误。

这是我的代码(Swift 3):

 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) let alertController = UIAlertController(title: "Foo", message: "Bar", preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) present(alertController, animated: true, completion: nil) } 

写下面的3行,我们所要做的就是这个。

Swift 3.0

 private func presentViewController(alert: UIAlertController, animated flag: Bool, completion: (() -> Void)?) -> Void { UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: flag, completion: completion) } 

Swift 2.0

  private func presentViewController(alert: UIAlertController, animated flag: Bool, completion: (() -> Void)?) -> Void { UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alert, animated: flag, completion: completion) } 

如果你想创build一个单独的类来显示类似这样的警告,NSObject的子类不是UIViewController。

并将从其启动的ViewController引用传递给showAlert函数,以便您可以在其中显示警报视图。

下面是Swift3中的Utility.swift类(不是UIViewController)中的UIAlertController的代码,谢谢Mitsuaki!

 private func presentViewController(alert: UIAlertController, animated flag: Bool, completion: (() -> Void)?) -> Void { UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: flag, completion: completion) } func warningAlert(title: String, message: String ){ let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) -> Void in })) // self.present(alert, animated: true, completion: nil) presentViewController(alert: alert, animated: true, completion: nil) } 

您可以使用bellow函数来调用任何只要在AnyClass中包含这些方法的警报

 class func topMostController() -> UIViewController { var topController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController while ((topController?.presentedViewController) != nil) { topController = topController?.presentedViewController } return topController! } class func alert(message:String){ let alert=UIAlertController(title: "AppName", message: message, preferredStyle: .alert); let cancelAction: UIAlertAction = UIAlertAction(title: "OK", style: .cancel) { action -> Void in } alert.addAction(cancelAction) AnyClass.topMostController().present(alert, animated: true, completion: nil); } 

然后打电话

 AnyClass.alert(message:"Your Message")