Is it possible to determine whether ViewController

2019-01-12 17:29发布

Is it possible to check inside ViewController class that it is presented as modal view controller?

14条回答
时光不老,我们不散
2楼-- · 2019-01-12 17:44

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.

查看更多
姐就是有狂的资本
3楼-- · 2019-01-12 17:45

Best way to check

 if (self.navigationController.presentingViewController) {
         NSLog(@"Model Present");
    }
查看更多
唯我独甜
4楼-- · 2019-01-12 17:45

In my project I have a view controller (Detail) that can be presented either modally (when adding a new item) or with push (when editing an existing one) by Master view controller. When user taps [Done] the Detail view controller calls Master view controller's method to notify that it is ready to be closed. Master has to determine how Detail is presented in order to know how to close it. This is how I do this:

UIViewController *vc = self.navigationController.viewControllers.lastObject;
if (vc == self) {
    [self dismissViewControllerAnimated:YES completion:NULL];
} else {
    [self.navigationController popViewControllerAnimated:YES];
}
查看更多
Root(大扎)
5楼-- · 2019-01-12 17:49

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
查看更多
聊天终结者
6楼-- · 2019-01-12 17:49

Here's my modified version of @GabrielePetronella's isModal, which works with contained view controllers in that it walks up the parentViewController hierarchy first. Also pulled the code out into multiple lines so it's clear what it's doing.

var isModal: Bool {
    // If we are a child view controller, we need to check our parent's presentation
    // rather than our own.  So walk up the chain until we don't see any parentViewControllers
    var potentiallyPresentedViewController : UIViewController = self
    while (potentiallyPresentedViewController.parentViewController != nil) {
        potentiallyPresentedViewController = potentiallyPresentedViewController.parentViewController!
    }

    if self.presentingViewController?.presentedViewController == potentiallyPresentedViewController {
        return true
    }

    if let navigationController = potentiallyPresentedViewController.navigationController {
        if navigationController.presentingViewController?.presentedViewController == navigationController {
            return true
        }
    }

    return potentiallyPresentedViewController.tabBarController?.presentingViewController is UITabBarController
}
查看更多
贼婆χ
7楼-- · 2019-01-12 17:50

A hack like this might work.

UIViewController* child = self;
UIViewController* parent = child.parentViewController;
while (parent && parent.modalViewController != child) {
    child = parent;
    parent = child.parentViewController;
}
if (parent) {
    // A view controller in the hierarchy was presented as a modal view controller
}

However, I think my previous answer is a cleaner solution.

查看更多
登录 后发表回答