Swift 3, Xcode 8.1. I want to display UIAlertController
in 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)
}
Full code of this class you can find here
I call the method presentAlert in viewDidLoad
:
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!
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.
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
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.
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.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With