开发者

How to tell if there is a modal UIViewController presented?

开发者 https://www.devze.com 2023-03-26 16:53 出处:网络
Is there a way to tell whether there is a modal UIViewController presented already, say, before c开发者_StackOverflowalling dismissModalViewControllerAnimated?iOS 9, 8, 7, 6 & 5

Is there a way to tell whether there is a modal UIViewController presented already, say, before c开发者_StackOverflowalling dismissModalViewControllerAnimated?


iOS 9, 8, 7, 6 & 5

There are just too many answers to this question, none covering all cases. Furthermore, despite what you find in the documentation, there are two alternatives to the now deprecated modalViewController:

  1. If you need to know if you are modal:

    BOOL modal = nil != [self presentingViewController];

  2. If you need to know if you are covered by a modal:

    BOOL hiddenByModal = nil != [self presentedViewController];


iOS6+ - use presentedViewController: Since iOS 6, presentedViewController should be used instead as the modalViewController which has been deprecated

Use the property:

Deprecated - modalViewController: The controller for the active modal view—that is, the view that is temporarily displayed on top of the view managed by the receiver. (read-only)

@property(nonatomic, readonly) UIViewController *modalViewController


I usually add a BOOL variable, called something like isModal, and I set it after initializing a viewcontroller but before calling presentModalViewController. Something like:

MyViewController *controller = [[MyViewController alloc] init];
controller.isModal = YES;
[self presentModalViewController:controller animated:YES];

And then, in MyViewController, before needing to dismiss, I just check:

if (isModal) { //dismiss modal }


after iOS 5 you should use:

if (self.presentingViewController != nil) {

     [self dismissViewControllerAnimated:YES completion:^{

    //has dismissViewControllerAnimated
    }];
}

Edited to change iOS Version


I understand this has been a while but just wanted do add my 2 cents to this matter.

I was in need to identify if there was a modally presented ViewController when the app went to background in order to dismiss it first.

First I made an extension of UIWindow to return me the current ViewController:

extension UIWindow {

    func getCurrentViewController() -> UIViewController? {

        guard let rvc = self.rootViewController else {
            return nil
        }

        if let pvc = rvc.presentedViewController {

            return pvc

        } else if let svc = rvc as? UISplitViewController, svc.viewControllers.count > 0 {

            return svc.viewControllers.last!

        } else if let nc = rvc as? UINavigationController, nc.viewControllers.count > 0 {

            return nc.topViewController!

        } else if let tbc = rvc as? UITabBarController {

            if let svc = tbc.selectedViewController {

                return svc
            }
        }

        return rvc
    }
}

Then I went into appDelegate and added a test on applicationDidEnterBackground():

func applicationDidEnterBackground(_ application: UIApplication) {

    if let vc = self.window?.getCurrentViewController() {

        if vc.presentingViewController != nil {

            vc.dismiss(animated: false, completion: nil)
        }
    }
}

This solution is in Swift 3

0

精彩评论

暂无评论...
验证码 换一张
取 消