Search code examples
iosswiftuialertcontroller

show UIAlertController outside of ViewController


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 alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)

Which is not working... I didn't find any solution that worked for me yet.


Solution

  • 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.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 if let presented = controller.presentedViewController {
                presentFromController(controller: presented, animated: animated, completion: completion)
            } else {
                controller.present(self, animated: animated, completion: completion);    
            }
        }
    }
    

    Now it's as easy as:

    var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)
    alertController.show()