如何检查导航控制器是否已推送或作为根视图控制器?

16

我想检查当前所在的视图控制器是根视图控制器还是被推到某个导航控制器上。


1
检查 self.navigationController.viewControllers,它会给你一个推入的导航视图控制器数组。 - ChintaN -Maddy- Ramani
1
你可以使用 self.navigationController.topViewController == self 来检查它是否是 rootViewController - gabbler
4个回答

19

[self.navigationController viewControllers];

将返回一个包含堆栈上所有视图控制器的数组。只需比较此数组中的第一个元素,以查看控制器是否是根控制器。

例如:

UIViewController *vc = [[self.navigationController viewControllers] firstObject];

if([vc isEqual: <viewController to check> ])
{
    // code here
}

编辑:添加了Swift

let vc = self.navigationController?.viewControllers.first
if vc == self.navigationController?.visibleViewController {
    //Code Here
}

请注意,此答案是正确的,下面的答案不正确。当堆栈具有> 1个元素时,仍然存在一个根视图控制器位于该堆栈顶部! - RobP
@RobP - 我同意根控制器将位于堆栈的0号索引,即使堆栈有>1个元素。但是,当前视图控制器即topViewController只有在堆栈中只有一个控制器时才能成为根控制器。在堆栈>1个元素的情况下,topViewController将始终与根控制器不同。在这个答案中,_Simon_正在检查特定的视图控制器是否等于根控制器,这不是被问到的问题。 - Gandalf
@Gandalf,问题是给定的viewController是否为根视图控制器。这就是我的回答。当然,还有其他方法可以做到这一点,但这并不是错误的。 - Simon McLoughlin
@SimonMcLoughlin - 不,我不是说这是错误的,但问题是“如果我所在的视图控制器是根视图控制器”,这意味着当前或topViewController或导航堆栈中的最后一个对象。为了成为根,它必须是堆栈的第一个对象,因为根始终位于0号索引处。我希望你明白我的意思。 - Gandalf
1
问题在于“current”的定义--它应该表示“代码当前正在执行”,而不是“当前最顶层或可见”。 - RobP
显示剩余2条评论

9
每当您通过导航控制器推送任何视图控制器时,它会以后进先出(Last In First Out)的方式在堆栈中管理这些视图控制器。因此,如果您当前的视图控制器是根控制器,那么堆栈中只能有一个对象。您可以使用以下代码检查该堆栈。
if([self.navigationController.viewControllers count] == 1)  {  
   //Current view controller is root controller  
}

4

在您当前的视图控制器的viewDidLoad中,只需检查self.navigationController.viewControllers.count == 1,意味着您当前位于导航堆栈的根视图。确保您没有呈现视图控制器。

if(self.navigationController.viewControllers.count == 1)
{
    //do what you want
}

2

关于@Simon的回答,我补充一下我的答案。如果你使用了一些抽屉式菜单,这可能会帮助你找到确切的根视图控制器。

- (BOOL) checkImRoot:(id)controller {
    if(self.window.rootViewController) {
        if(self.window.rootViewController == (UIViewController *)controller) {
            return YES;
        }
    }
    return NO;
}

例如,我在应用程序代理文件中添加了此方法,并像这样调用它进行检查,
if([[AppDelegate shareDelegate] checkImRoot:self]) {
     //Yeah, I'm a root vc
}else{
     //Noo, I'm a child vc
}

你难道没有多余的 self.window.rootViewController 吗?!这是一个错误吗? - mfaani
不是错误。我只是在访问“window”属性。 - Hemang
我还是不明白。你可以直接在第二行写出来...如果不成立就返回 nil。为什么要多一行?! - mfaani
1
@Honey,如果rootViewController为空,我们的比较可能会导致代码崩溃。 - Hemang
1
哈哈,你说得对。我来自一个Swift的世界,在那里rootViewController是可选的... - mfaani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接