iOS版。尝试在UIViewController上呈现UIAlertController,其视图不在窗口层次结构中

时间:2022-10-30 08:55:43

Swift 3, Xcode 8.1. I want to display UIAlertController in UIViewController.

Swift 3,Xcode 8.1。我想在UIViewController中显示UIAlertController。

I have methods:

我有方法:

private static func rootViewController() -> UIViewController {
    // cheating, I know

    return UIApplication.shared.keyWindow!.rootViewController!
}

static func presentAlert(_ message: String) {
    let alertView = UIAlertController(title: "RxExample", message: message, preferredStyle: .alert)
    alertView.addAction(UIAlertAction(title: "OK", style: .cancel) { _ in })

    rootViewController().present(alertView, animated: true, completion: nil)
}

Full code of this class you can find here

您可以在此处找到此课程的完整代码

I call the method presentAlert in viewDidLoad:

我在viewDidLoad中调用presentAlert方法:

override func viewDidLoad() {
    super.viewDidLoad()
    DefaultWireframe.presentAlert("test")
    ...
}

and got the warning:

并得到警告:

Warning: Attempt to present UIAlertController: 0x7f904ac0d930 on UIViewController: 0x7f904ad08040 whose view is not in the window hierarchy!

警告:尝试在UIViewController上显示UIAlertController:0x7f904ac0d930:0x7f904ad08040,其视图不在窗口层次结构中!

How to avoid the warning and display the Alert?

如何避免警告并显示警报?

It works when I try to show Alert in initial ViewController, but it doesn't work in another ViewController connected using push segue with initial VC.

它在我尝试在初始ViewController中显示Alert时有效,但它在使用push segue与初始VC连接的另一个ViewController中不起作用。

2 个解决方案

#1


20  

In viewDidLoad, your app has not presented the view controller to the user yet, so an alert cannot be shown. Try executing that code in viewDidAppear

在viewDidLoad中,您的应用尚未向用户显示视图控制器,因此无法显示警报。尝试在viewDidAppear中执行该代码

#2


3  

I had similar problem/case where action sheet was not showing on a ViewController which was pushed on another ViewController. The error it was giving was also similar as your's. What you have done works perfectly on normal ViewControllers but just doesn't work on the ViewControllers which are pushed over other ViewController.

我有类似的问题/案例,其中没有在另一个ViewController上推送的ViewController上显示操作表。它给出的错误也与你的错误相似。你所做的工作在普通的ViewControllers上运行得很好,但是对于推到其他ViewController上的ViewControllers不起作用。

I solved the problem by making the object of class UIAlertController as an instance variable of my class rather than keeping it local inside the triggering function.

我通过将类UIAlertController的对象作为我的类的实例变量而不是将其保持在触发函数内部来解决问题。

So in your case, try declaring var alertView: UIAlertController? at top of the class where instance variables are declared and then just initialise it in your desired triggering function to use it like this:

那么在你的情况下,尝试声明var alertView:UIAlertController?在声明实例变量的类的顶部,然后在你想要的触发函数中初始化它,就像这样使用它:

static func presentAlert(_ message: String) {
    self.alertView = UIAlertController(title: "RxExample", message: message, preferredStyle: .alert)
    alertView.addAction(UIAlertAction(title: "OK", style: .cancel) { _ in })

    rootViewController().present(alertView, animated: true, completion: nil)
}

Might be some bug from Apple's side in maintaining reference which was causing this problem. But work around I wrote above works perfect.

可能是苹果方面的一些错误,在维护参考时引起了这个问题。但是我上面写的作品很完美。

#1


20  

In viewDidLoad, your app has not presented the view controller to the user yet, so an alert cannot be shown. Try executing that code in viewDidAppear

在viewDidLoad中,您的应用尚未向用户显示视图控制器,因此无法显示警报。尝试在viewDidAppear中执行该代码

#2


3  

I had similar problem/case where action sheet was not showing on a ViewController which was pushed on another ViewController. The error it was giving was also similar as your's. What you have done works perfectly on normal ViewControllers but just doesn't work on the ViewControllers which are pushed over other ViewController.

我有类似的问题/案例,其中没有在另一个ViewController上推送的ViewController上显示操作表。它给出的错误也与你的错误相似。你所做的工作在普通的ViewControllers上运行得很好,但是对于推到其他ViewController上的ViewControllers不起作用。

I solved the problem by making the object of class UIAlertController as an instance variable of my class rather than keeping it local inside the triggering function.

我通过将类UIAlertController的对象作为我的类的实例变量而不是将其保持在触发函数内部来解决问题。

So in your case, try declaring var alertView: UIAlertController? at top of the class where instance variables are declared and then just initialise it in your desired triggering function to use it like this:

那么在你的情况下,尝试声明var alertView:UIAlertController?在声明实例变量的类的顶部,然后在你想要的触发函数中初始化它,就像这样使用它:

static func presentAlert(_ message: String) {
    self.alertView = UIAlertController(title: "RxExample", message: message, preferredStyle: .alert)
    alertView.addAction(UIAlertAction(title: "OK", style: .cancel) { _ in })

    rootViewController().present(alertView, animated: true, completion: nil)
}

Might be some bug from Apple's side in maintaining reference which was causing this problem. But work around I wrote above works perfect.

可能是苹果方面的一些错误,在维护参考时引起了这个问题。但是我上面写的作品很完美。