IOS An attempt to present a UIAlertController on a UIViewController whose view is not in the window hierarchy

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

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

The full code for this class can be found here.

I call the presentAlert method in viewDidLoad :

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

and received a warning:

Warning: attempt to present UIAlertController: 0x7f904ac0d930 on UIViewController: 0x7f904ad08040, whose view is not in the hierarchy of windows!

How to avoid a warning and display a warning?

It works when I try to show Alert in the initial ViewController, but it does not work in another ViewController connected using push segue with the initial VC.

+5
source share
2 answers

In viewDidLoad, your application has not yet presented the view controller to the user, so the warning cannot be shown. Try executing this code in viewDidAppear

+17
source

I had a similar problem / case where the action sheet didn't show up in the ViewController that was clicked on by another ViewController. The error she gave was also similar to yours. What you did works fine on regular ViewControllers, but just doesn't work on ViewControllers that drag and drop through another ViewController.

I solved the problem by setting the UIAlertController class object as an instance variable of my class, rather than storing it locally inside the launch function.

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

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

There may be some error on the part of Apple in maintaining the link that causes this problem. But the work I wrote about above works great.

+3
source

Source: https://habr.com/ru/post/1259938/


All Articles