AlertController不在窗口层次结构中

wtz*_*znc 40 storyboard uialertview ios swift uialertcontroller

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

这是我的班级提醒.

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

这是执行警报的ViewController.

class ViewController: UIViewController {
   override func viewDidLoad() {
       super.viewDidLoad()  
   }

   @IBAction func showAlertButton(sender: AnyObject) {
       var alert = AlertController()
       alert.showAlert()
   }
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的,而不是美丽的警报.

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

我该怎么办?

Sko*_*oua 42

如果你是UIAlertController从一个模态控制器实例化你需要这样做viewDidAppear,而不是在viewDidLoad你或你会得到一个错误.

这是我的代码(Swift 4):

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)
}
Run Code Online (Sandbox Code Playgroud)


Sul*_*han 18

我们来看看你的视图层次结构.你有一个ViewController.然后你创建一个AlertController,你没有将它添加到你的层次结构中,你正在调用一个实例方法,它试图使用AlertControlleras present controller来显示另一个controller(UIAlertController).

+ ViewController
    + AlertController (not in hierarchy)
        + UIAlertController (cannot be presented from AlertController)
Run Code Online (Sandbox Code Playgroud)

简化代码

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)
   }
}
Run Code Online (Sandbox Code Playgroud)

这会奏效.

如果您需要AlertController某些内容,则必须先将其添加到层次结构中,例如使用addChildViewController或使用其他presentViewController调用.

如果您希望该类只是创建警报的帮助器,它应如下所示:

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

叫做

 var alert = AlertHelper()
 alert.showAlert(fromController: self)
Run Code Online (Sandbox Code Playgroud)


Var*_*ria 9

您可以使用以下函数从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);
    }
Run Code Online (Sandbox Code Playgroud)

然后打电话

AnyClass.alert(message:"Your Message")
Run Code Online (Sandbox Code Playgroud)


Mit*_*oto 5

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

斯威夫特3.0

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

斯威夫特2.0

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

  • 在这种情况下,仍然存在 rootViewControllers 视图被释放的情况(例如,当模态 vc 出现在它前面时)并且您的警报不会显示。您将收到错误“警告:尝试在其视图不在窗口层次结构中的 <根视图控制器> 上呈现 <警报>!” (5认同)