show UIAlertController outside of ViewController

前端 未结 4 2113
隐瞒了意图╮
隐瞒了意图╮ 2021-02-01 07:43

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          


        
相关标签:
4条回答
  • 2021-02-01 08:33

    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);
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-01 08:33

    This should work.

     UIApplication.sharedApplication().windows[0].rootViewController?.presentViewController(...)
    
    0 讨论(0)
  • 2021-02-01 08:36

    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
    }
    
    0 讨论(0)
  • 2021-02-01 08:42

    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
                        }
            }
    
    0 讨论(0)
提交回复
热议问题