22

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

尽可能我想,因为我在我的项目使用splitview,并选择不同的行中的主视图也将触发viewWillDisappear/viewDidDisappear方法使用viewWillDisappearviewDidDisappear望而却步。

+0

为什么不使用导航控制器的委托方法? – matt

+2

您仍然可以使用viewWillDissapear/viewDidDisappear并查明viewcontroller是否真的弹出。这可能有所帮助:http://stackoverflow.com/questions/1816614/viewwilldisappear-determine-whether-view-controller-is-being-popped-or-is-showi – Niraj

回答

20

UPDATE 20150430

基于phatmann的反馈(下面的第一个评论),我很好奇,如果有什么东西改变,因为我的回答在一年前这个问题。我编写了一个简单的示例应用程序,并获得了一些有趣的结果。

选项1,例如

https://github.com/greymouser/TestNVC

我没有能够轻松测试前8.x的能力,所以我不知道如果从那时开始,事情已经改变。然而,我最初描述的行为仍然发生。 但是,由于将测试应用程序放在一起,我确实注意到我以前从未有过的奇怪之处。

如果我只是依靠{will,did}MoveToParentViewController,我发现一个虚假的didMoveToParentViewController:调用时推荐rootVC上的第一个非rootVC,父母!= nil(暗示它被添加,不被删除)。在我的原始答案时间周围,我没有遇到这种情况,因为我通常在我的NVC上拥有“永久性”rootVC,并且没有在那里实施回调。请参阅日志设置为LOG_WILL_DID_MTPVC(在ViewController.m中)的示例应用程序。这是一个 - 编辑的空间 - 快照的我所看到的:单独使用{will,did}MoveToParentViewController

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] 
... 

我原来的答复建议,因为它是一个“一站式”处理这种行为。然而,现在我已经看到了rootVC的虚假呼叫,我建议混合使用{will,did}MoveToParentViewController以及标准UINavigationControllerDelegate回调。对于示例应用程序中的这种行为,请将日志记录设置为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

正在使用您的雷士sublcass,覆盖- pushViewController:animated:- popViewControllerAnimated:,并应用要在VC任何行为我没有探索另一种选择推,或从返回的VC流行。 (一定要记得打电话super在你重写,如果你尝试这个。)

更新汇总

所以,感谢phatmann用于为改变这一机会。我想我的回答是更多现在正确。但是,我不太确定它是否“完全不真实”。;-)

ORIGINAL

如果您所描述的确切行为是你在找什么,然后覆盖你的孩子视图控制器在以下方面:

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

willMoveToParentViewController:将调用与父母!=输入时为零,并且在离开时父母==零。 didMoveToParentViewController:将始终有父!=零。

有时,viewDidDisappear可能是有意义的。但是,如果您真的想从父容器视图控制器中查找push和pop,那么上面的这些方法就是您想要的。

+0

至少在iOS 8中,不会调用'willMoveToParentViewController'用于导航控制器中的子视图控制器。当子视图控制器最初放置在导航视图控制器中时,除了在弹出时调用时,还会调用“didMoveToParentViewController”。所以这些方法对于OP所需要的是没有用的。没有选择,只能downvote。 – phatmann

+0

@phatmann感谢您的反馈。我已经用示例应用程序和日志记录更新了我的答案。您的评论帮助我确定了我没有注意到的与我的第一个答案有关的问题,但是,我认为您的问题/要点也不是100%正确的。请参阅更新以获取完整说明。干杯! – greymouser

+0

哇,很好的研究,谢谢你这样做。现在upvoted :-)但是,苹果让这些电话很奇怪,我会继续避免它们。最好使用一个布尔值,就像那样。 – phatmann

43

可以检测是否一个视图是使用isMovingFromParentViewController属性视图控制器被弹出,如下所示:

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

isMovingFromParentViewController

返回一个布尔值,指示该视图控制器在 被从其父母移除的过程。

+0

这应该是公认的答案 –

+0

@Nishant我明白,视图消失时调用了MovingFromParentViewController,但视图可以消失,因为ViewController被推入或弹出。当viewController被推入导航堆栈时,或只有当它被固定时(例如后退按钮),该方法isMovingFromParentViewController是否也被调用? – bibscy

+0

@bibscy'isMovingFromParentViewController'仅在视图控制器被弹出而未被压入时被调用。 –

相关问题