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
:
If you need to know if you are modal:
BOOL modal = nil != [self presentingViewController];
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 themodalViewController
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
精彩评论