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

时间:2014-02-20 17:29:31

标签: ios objective-c cocoa-touch uiviewcontroller uinavigationcontroller

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

我希望尽可能远离使用viewWillDisappearviewDidDisappear,因为我在项目中使用splitview,并在主视图中选择不同的行将还会触发viewWillDisappear / viewDidDisappear方法。

5 个答案:

答案 0 :(得分:77)

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

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

<强> isMovingFromParentViewController

     

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

答案 1 :(得分:22)

更新20150430

基于phatmann的反馈(下面的第一条评论),我很好奇自从我在一年前回答这个问题以来发生了什么变化。我整理了一个简单的示例应用程序,并且有一些有趣的结果。

选项1,示例

https://github.com/greymouser/TestNVC

我没有能力轻松测试8.x之前的版本,所以我不确定自那时起是否有变化。但是,我最初描述的行为仍然会发生。 然而,多亏了将测试应用程序放在一起,我确实注意到了之前没有的奇怪之处。

如果我只依赖{will,did}MoveToParentViewController,我注意到在rootVC上推送第一个非rootVC时出现虚假的didMoveToParentViewController:调用,使用parent!= nil(暗示它已被添加,未被删除) )。我在原始答案的时候没有遇到过这个问题,因为我通常在我的NVC上有“永久”rootVC,并且没有在那里实现回调。请参阅示例应用,将日志记录设置为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]
...

我的原始答案建议单独使用{will,did}MoveToParentViewController,因为它是处理此行为的“一站式服务”。但是,既然我已经看到了对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

我没有探索的另一个选择是使用您的NVC sublcass,覆盖- pushViewController:animated:- popViewControllerAnimated:,并将您想要的任何行为应用于被推送的VC,或者从pop返回的VC 。 (如果您尝试这样做,请务必记住在覆盖中调用super。)

更新摘要

所以,感谢phatmann有机会重新开始。我认为现在我的回答是更多正确。但是,我不太确定它是否“完全不真实”。 ; - )

<强> ORIGINAL

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

- (void)willMoveToParentViewController:(UIViewController *)parent;
- (void)didMoveToParentViewController:(UIViewController *)parent;
输入时将使用parent!= nil调用

willMoveToParentViewController:,并在离开时调用parent == nil。 didMoveToParentViewController:将永远有父!= nil。

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

答案 2 :(得分:0)

对于Swift用户(Swift 3-4.2):

我想检测何时从堆栈中弹出视图控制器,所以我无法使用viewWillDisappearviewDidDisappear回调,因为这些回调将在视图控制器被调用时被调用不再可见,并且从堆栈中弹出时也不再可见。

但是您可以通过执行以下操作来使用导航控制器“委托” UINavigationControllerDelegate

让您的控制器符合UINavigationControllerDelegate

class ViewController : UIViewController {

      override func viewDidLoad() {
          super.viewDidLoad()
          self.navigationController?.delegate = self
      }

}




extension ViewController : UINavigationControllerDelegate {

     override func willMove(toParentViewController parent: UIViewController?) {

     /*You can detect here when the viewcontroller is being popped*/

     }

}

希望这会有所帮助,祝你好运

答案 3 :(得分:0)

如果您不需要在删除视图控制器之前就知道它,而只需要知道它已被弹出,则也可以使用deinit

class ViewController: UIViewController {

    deinit {
        // View controller has been popped/dismissed and it's being released
    }
}

此方法可以很好地通知协调员或其他代表。

答案 4 :(得分:0)

我在iOS 13上的经验是Sub SelectAllEquations() Dim xMath As OMath Dim I As Integer With ActiveDocument .DeleteAllEditableRanges wdEditorEveryone For I = 1 To .OMaths.Count Set xMath = .OMaths.Item(I) xMath.Range.Paragraphs(1).Range.Editors.Add wdEditorEveryone Next .SelectAllEditableRanges wdEditorEveryone .DeleteAllEditableRanges wdEditorEveryone End With End Sub 的属性值并不总是一致的。当搜索控制器处于活动模式时(点按搜索文本字段),返回到父视图将为此属性设置isMovingFromParent值。

这是我确定视图是否来自父视图的方法:

false