I have trouble to display my UIAlertController because I\'m trying to show it in a Class which is not an ViewController.
I already tried adding it:
var
I wrote this extension
over UIAlertController
to bring back show()
.
It uses recursion to find the current top view controller:
extension UIAlertController {
func show() {
present(animated: true, completion: nil)
}
func present(#animated: Bool, completion: (() -> Void)?) {
if let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController {
presentFromController(rootVC, animated: animated, completion: completion)
}
}
private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) {
if let navVC = controller as? UINavigationController,
let visibleVC = navVC.visibleViewController {
presentFromController(visibleVC, animated: animated, completion: completion)
} else
if let tabVC = controller as? UITabBarController,
let selectedVC = tabVC.selectedViewController {
presentFromController(selectedVC, animated: animated, completion: completion)
} else {
controller.presentViewController(self, animated: animated, completion: completion);
}
}
}
Now it's as easy as:
var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)
alertController.show()
EDIT:
For Xcode 8.0 & Swift 3:
extension UIAlertController {
func show() {
present(animated: true, completion: nil)
}
func present(animated: Bool, completion: (() -> Void)?) {
if let rootVC = UIApplication.shared.keyWindow?.rootViewController {
presentFromController(controller: rootVC, animated: animated, completion: completion)
}
}
private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) {
if let navVC = controller as? UINavigationController,
let visibleVC = navVC.visibleViewController {
presentFromController(controller: visibleVC, animated: animated, completion: completion)
} else
if let tabVC = controller as? UITabBarController,
let selectedVC = tabVC.selectedViewController {
presentFromController(controller: selectedVC, animated: animated, completion: completion)
} else {
controller.present(self, animated: animated, completion: completion);
}
}
}
This should work.
UIApplication.sharedApplication().windows[0].rootViewController?.presentViewController(...)
Create a helper function that you call from the current view controller and pass the current view controller as a parameter:
func showAlertInVC(
viewController: UIViewController,
title: String,
message: String)
{
//Code to create an alert controller and display it in viewController
}
If you solution is not working it probably because of there is no window at that moment. I had the same problem when I was trying to show alert view in application:DidFinishLoadingWithOptions
method. In this case my solution was to check if root view controller is available, and if it's not, then add notification for UIApplicationDidBecomeActiveNotification
NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationDidBecomeActiveNotification,
object: nil,
queue: NSOperationQueue.mainQueue()) {
(_) in
//show your alert by using root view controller
//remove self from observing
}
}