确定是否以模态方式呈现UIViewController

时间:2010-12-04 21:32:29

标签: objective-c ios

我的应用程序的主窗口包含一个基于xib的UITabBarController(在Interface Builder中完全配置),也可以模态呈现(很像Music.app“将歌曲添加到播放列表”模态视图)。 UITabBarController包含许多UINavigationControllers,后者又包含子类UITableViewControllers。这就是我当前正在检测是否在模式UITabBarController中呈现子类UITableViewController:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.isModal = NO;

    UIViewController *child     = self;
    UIViewController *parent    = self.parentViewController;
    while (parent) {
        if (parent.modalViewController && parent.modalViewController == child) {
            self.isModal = YES;
            break;
        }
        child   = parent;
        parent  = parent.parentViewController;
    }

    if (self.isModal) {
        // modal additions, eg. Done button, navigationItem.prompt
    }
    else {
        // normal additions, eg. Now Playing button
    }
}

有没有办法做到这一点,不涉及走向parentViewController树或继承所有中间视图控制器以在初始化时传递isModal状态?

6 个答案:

答案 0 :(得分:10)

如果你正在寻找iOS 6+,这个答案已被弃用,你应该检查Gabriele Petronella's answer


前一段时间我回答了一个非常类似的问题,我有一个函数来确定当前控制器是否显示为模态,而不需要在此处对标签栏控制器进行子类化:

Is it possible to determine whether ViewController is presented as Modal?

在原始答案中,有一些关于这个功能如何工作的基本解释,如果需要你可以在那里检查,但这里是

-(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;        

}

答案 1 :(得分:4)

Got an answer on Twitter。我最后继承了UITabBarController并添加了一个BOOL isModal实例属性,当以模态方式呈现时,该属性设置为YES。然后子视图可以使用self.tabBarController对子类进行强制转换以访问isModal属性并相应地渲染/表现。

答案 2 :(得分:4)

从iOS5开始,您还可以在viewController实例上使用 isBeingPresented

- (BOOL)isModalViewController
{
    return [self isBeingPresented];
}

答案 3 :(得分:2)

我会看看获取根视图控制器并检查它是否有模态视图控制器。您可以从UIWindow获取该视图控制器。另请注意,您可以使用UINavigationController的viewControllers属性迭代当前视图控制器的层次结构:for(UIViewController * viewController in self.navigationController.viewControllers){...}更快更简单。

答案 4 :(得分:1)

您可以在显示视图时在自定义初始化程序中设置显示状态。我的意思是呈现它的代码会知道它是如何呈现的,对吗?

- (void)initInModalMode:(BOOL)isModal

最好让视图在以后追溯发现它的状态?

答案 5 :(得分:0)

在这些斯威夫特时代,有一种更容易的方式。

extension UIViewController {

    var isPresentedModally: Bool {
        return presentingViewController?.presentedViewController == self || parent?.isPresentedModally == true
    }

}