如何检测视图控制器是否从导航控制器中popup?

我目前需要实现一些代码,当从我的导航控制器popup顶视图控制器。 有没有办法检测视图控制器何时从导航控制器堆栈popup?

尽可能多的我想远离使用viewWillDisappearviewDidDisappear因为我在我的项目中使用了splitview视图,并且在主视图中select不同的行也会触发viewWillDisappear / viewDidDisappear方法。

您可以使用视图控制器的isMovingFromParentViewController属性来检测是否正在popup视图,如下所示:

 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if ([self isMovingFromParentViewController]) { NSLog(@"View controller was popped"); } else { NSLog(@"New view controller was pushed"); } } 

isMovingFromParentViewController

返回一个布尔值,指示视图控制器正在从其父项中移除。

更新20150430

根据phatmann的反馈(下面的第一条评论),我很好奇自从我一年前回答这个问题以来是否有什么改变。 我把一个简单的示例应用程序放在一起,并有一些有趣的结果。

选项1,例子

https://github.com/greymouser/TestNVC

我没有能力轻松testing8.x之前的版本,所以我不确定自那以后有什么改变。 然而,我原来描述的行为仍然发生。 但是 ,由于将testing应用程序放在一起,我确实注意到我以前从未有过的奇怪之处。

如果我只是依赖{will,did}MoveToParentViewController ,我注意到一个虚假的didMoveToParentViewController:调用时,推荐第一个非rootVC,在rootVC,与父!= nil(暗示它被添加,不被删除)。 在我原来的回答中,我并没有遇到这种情况,因为我通常在我的NVC上拥有“永久性”rootVC,并且没有在那里执行callback。 将日志logging设置为LOG_WILL_DID_MTPVC的示例应用程序(在ViewController.m中)。 这是一个编辑的空间快照我所看到的:

 TestNVC[] -[vc(rootVC) willMoveToParentViewController [entering] TestNVC[] -[vc(rootVC) didMoveToParentViewController [entering] TestNVC[] -[vc(1) willMoveToParentViewController [entering] TestNVC[] -[vc(rootVC) didMoveToParentViewController [entering] # <-- this is odd TestNVC[] -[vc(1) didMoveToParentViewController [entering] ... 

我原来的答案build议单独使用{will,did}MoveToParentViewController ,因为它是处理这种行为的“一站式服务”。 然而,现在我已经看到了对VCVC的虚假调用,我build议混合{will,did}MoveToParentViewController以及标准的UINavigationControllerDelegatecallback。 对于示例应用程序中的这种行为,请将日志logging设置为LOG_WILL_DID_MTPVC_LEAVING_AND_NVC_WILL_DID_SHOW_VC 。 现在我们看到以下内容:

 TestNVC[] -[nvcD willShowViewController]: rootVC TestNVC[] -[nvcD didShowViewController]: rootVC TestNVC[] -[nvcD willShowViewController]: 1 TestNVC[] -[nvcD didShowViewController]: 1 TestNVC[] -[nvcD willShowViewController]: 2 TestNVC[] -[nvcD didShowViewController]: 2 TestNVC[] -[vc(2) willMoveToParentViewController [leaving] TestNVC[] -[nvcD willShowViewController]: 1 TestNVC[] -[vc(2) didMoveToParentViewController [leaving] TestNVC[] -[nvcD didShowViewController]: 1 TestNVC[] -[vc(1) willMoveToParentViewController [leaving] TestNVC[] -[nvcD willShowViewController]: rootVC TestNVC[] -[vc(1) didMoveToParentViewController [leaving] TestNVC[] -[nvcD didShowViewController]: rootVC 

…这现在更有意义了。

选项2

我没有探索的另一个select是使用你的NVC sublcass,覆盖- pushViewController:animated:- popViewControllerAnimated:并且将你想要的任何行为应用到被推送的VC,或者从pop中返回的VC。 (如果你尝试这样的话,一定要记得在你的覆盖中调用super 。)

更新摘要

所以,感谢phatmann有机会读这个。 我想现在我的答案更为正确。 但是,我不太确定它是否“完全不真实”。 😉

原版的

如果您描述的确切行为是您正在查找的内容,请在子视图控制器上覆盖以下内容:

 - (void)willMoveToParentViewController:(UIViewController *)parent; - (void)didMoveToParentViewController:(UIViewController *)parent; 

willMoveToParentViewController:在进入时将被调用,parent!= nil,而parent == nil在离开时调用。 didMoveToParentViewController:将始终有父!= nil。

有时, viewDidDisappear可能是有道理的。 然而,如果你真的从父容器视图控制器中寻找push和pop,那么上面的方法就是你想要的。