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.
Views are for display, model objects are for data, controllers are the glue in between them.
A view controller manages a single root view, which may itself contain any number of subviews. User interactions with that view hierarchy are handled by your view controller, which coordinates with other objects of your app as needed. Every app has at least one view controller whose content fills the main window.
Since modalViewController
has been deprecated in iOS 6, here's a version that works for iOS 5+ and that compiles without warnings.
Objective-C:
- (BOOL)isModal {
return self.presentingViewController.presentedViewController == self
|| (self.navigationController != nil && self.navigationController.presentingViewController.presentedViewController == self.navigationController)
|| [self.tabBarController.presentingViewController isKindOfClass:[UITabBarController class]];
}
Swift:
var isModal: Bool {
return self.presentingViewController?.presentedViewController == self
|| (self.navigationController != nil && self.navigationController?.presentingViewController?.presentedViewController == self.navigationController)
|| self.tabBarController?.presentingViewController is UITabBarController
}
Hat tip to Felipe's answer.
If you a looking for iOS 6+, this answer is deprecated and you should check Gabriele Petronella's answer
There is no neat way to do that, as a property or method native to UIKit. What you can do is to check several aspects of your controller to ensure it is presented as modal.
So, to check if the current (represented as self
in the code bellow) controller is presented in a modal way or not, I have the function bellow either in a UIViewController
category, or (if your project does not need to use other UIKit controllers, as UITableViewController
for example) in a base controller that my other controllers inherit of
-(BOOL)isModal {
BOOL isModal = ((self.parentViewController && self.parentViewController.modalViewController == self) ||
//or if I have a navigation controller, check if its parent modal view controller is self navigation controller
( self.navigationController && self.navigationController.parentViewController && self.navigationController.parentViewController.modalViewController == self.navigationController) ||
//or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
[[[self tabBarController] parentViewController] isKindOfClass:[UITabBarController class]]);
//iOS 5+
if (!isModal && [self respondsToSelector:@selector(presentingViewController)]) {
isModal = ((self.presentingViewController && self.presentingViewController.modalViewController == self) ||
//or if I have a navigation controller, check if its parent modal view controller is self navigation controller
(self.navigationController && self.navigationController.presentingViewController && self.navigationController.presentingViewController.modalViewController == self.navigationController) ||
//or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
[[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]]);
}
return isModal;
}
EDIT: I added the last check to see if a UITabBarController is being used, and you present another UITabBarController as modal.
EDIT 2: added iOS 5+ check, where UIViewController
does not answer for parentViewController
anymore, but to presentingViewController
instead.
EDIT 3: I've created a gist for it just in case https://gist.github.com/3174081
In iOS5+, As you can see in UIViewController Class Reference, you can get it from property "presentingViewController".
presentingViewController The view controller that presented this view controller. (read-only)
@property(nonatomic, readonly) UIViewController *presentingViewController
Discussion
If the view controller that received this message is presented by another view controller, this property holds the view controller that is presenting it. If the view controller is not presented, but one of its ancestors is being presented, this property holds the view controller presenting the nearest ancestor. If neither the view controller nor any of its ancestors are being presented, this property holds nil.
Availability
Available in iOS 5.0 and later.
Declared In
UIViewController.h
If there isn't, you can define a property for this (presentedAsModal
) in your UIViewController subclass and set it to YES
before presenting the ViewController as a modal view.
childVC.presentedAsModal = YES;
[parentVC presentModalViewController:childVC animated:YES];
You can check this value in your viewWillAppear
override.
I believe there isn't an official property that states how the view is presented, but nothing prevents you from creating your own.
Petronella's answer does not work if self.navigationController is modally presented but self is not equal to self.navigationController.viewControllers[0], in that case self is pushed.
Here is how you could fix the problem.
return self.presentingViewController.presentedViewController == self
|| (self.navigationController != nil && self.navigationController.presentingViewController.presentedViewController == self.navigationController && self == self.navigationController.viewControllers[0])
|| [self.tabBarController.presentingViewController isKindOfClass:[UITabBarController class]];
And in Swift:
return self.presentingViewController?.presentedViewController == self
|| (self.navigationController != nil && self.navigationController?.presentingViewController?.presentedViewController == self.navigationController && self.navigationController?.viewControllers[0] == self)
|| self.tabBarController?.presentingViewController is UITabBarController
This should work.
if(self.parentViewController.modalViewController == self)…
Best way to check
if (self.navigationController.presentingViewController) {
NSLog(@"Model Present");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With