Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 967
Michael Avatar asked May 05 '15 11:05

Michael


People also ask

How do you dismiss an alert with click on outside of the alert iOS?

Step 1 − Open Xcode and create a single view application and name it UIAlertSample. So basically, when we tap on the button an alert will be displayed, when the user taps outside the alert the alert will be dismissing.

How do I know if ViewController is visible?

The view's window property is non-nil if a view is currently visible, so check the main view in the view controller: Invoking the view method causes the view to load (if it is not loaded) which is unnecessary and may be undesirable. It would be better to check first to see if it is already loaded.


2 Answers

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()
like image 187
Aviel Gross Avatar answered Sep 23 '22 04:09

Aviel Gross


This should work.

 UIApplication.sharedApplication().windows[0].rootViewController?.presentViewController(...)
like image 35
Steve Glick Avatar answered Sep 24 '22 04:09

Steve Glick