简体   繁体   中英

How to tell if there is a modal UIViewController presented?

有没有办法告诉在调用dismissModalViewControllerAnimated之前是否已经提供了模态UIViewController?

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

after iOS 5 you should use:

if (self.presentingViewController != nil) {

     [self dismissViewControllerAnimated:YES completion:^{

    //has dismissViewControllerAnimated
    }];
}

Edited to change iOS Version

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 }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM