调用 popToRootViewControllerAnimated 时未调用 viewWillDisappear

Posted

技术标签:

【中文标题】调用 popToRootViewControllerAnimated 时未调用 viewWillDisappear【英文标题】:viewWillDisappear not called when calling popToRootViewControllerAnimated 【发布时间】:2013-07-30 18:14:38 【问题描述】:

我在一个遗留应用程序上工作,并发现我的 view[Will/Did]Disappear 方法并不总是正确触发。

情况是,我在 AppDelegate 中有一个(自定义)UIViewController 设置为 rootViewController。这个 rootViewController 有一个UINavigationController,上面推送了两个视图控制器。当用户按下主页按钮时,用户退出。当他稍后返回应用程序时,应用程序调用[UINavigationController popToRootViewControllerAnimated:YES],然后显示一个模式UIViewController 用于登录。

问题是:当我正常推送/弹出UINavigationController 时,我的viewWillDisappear 方法被正确调用。但是当我使用popToRootViewControllerAnimated: 方法时,不会在任何弹出的视图控制器上调用viewWillDisappear

在互联网上搜索只给出了两个可能的原因:

If using a UINavigationController as a subview, you must call view[Will/Did]Disappear yourself Not calling the proper super methods

这些建议都不适用于我的应用。我不知道去哪里找。有人对应用程序中的错误有什么建议吗?

【问题讨论】:

很好的发现:)。谢谢! 【参考方案1】:

视图可能不在屏幕上。要调用 viewWillDisappear: 方法,它必须在屏幕上(可见)。如果它从后台返回,则它是不可见的。

您可以尝试使用willMoveToParentViewController:,当视图控制器从其父级移除时调用。

【讨论】:

这是一个非常有趣的建议!我现在尝试在应用程序的另一个位置使用 popToRootViewController,然后按预期调用我的 viewWillDisappear,所以到目前为止你是对的。但是,我也尝试使用我的设置制作一个测试应用程序,其中 popToRootViewControllerAnimated: 是从 AppDelegate 的 applicationDidBecomeActive: 调用的。这里还调用了viewWillDisappear: 方法。这仍然表明应该调用它,但我的应用程序有问题。 发生这种情况的原因是,当调用applicationDidBecomeActive: 方法时(就在调用popToRootViewControllerAnimated: 之后),我正在呈现一个模态视图控制器。所以你的答案是正确的 - 当应用启动时,视图显然不在屏幕上。 在通过 Apple 的技术支持提出这个问题后,它原来是 ios 中的一个错误(它出现在 6 和 7 Beta 5 中)。我已经向 Apple 提交了错误报告。对于使用willMoveToParentViewController 作为解决方法的好建议,我给你+1 :-) @JRV 很高兴知道,感谢您的麻烦。您可能也想将其发布在 Open Radar (openradar.appspot.com) 上,以便人们了解它。 有趣的页面 - 感谢您指出。我现在已经发布了这个错误:openradar.appspot.com/14744330【参考方案2】:

对我很有用

[nav performSelector:@selector(popToRootViewControllerAnimated:) withObject:nil afterDelay:0.0];

我重写了 UITabBarController

- (void)setSelectedIndex:(NSUInteger)selectedIndex 

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
        UINavigationController *navigationController = [originalViewController as:[UINavigationController class]];
        if (navigationController.presentedViewController) 
            [navigationController dismissViewControllerAnimated:NO completion:^
                [navigationController popToRootViewControllerAnimated:NO];
            ];
        else if (navigationController.topViewController)
            [navigationController popToRootViewControllerAnimated:NO];
        
    );

【讨论】:

以上是关于调用 popToRootViewControllerAnimated 时未调用 viewWillDisappear的主要内容,如果未能解决你的问题,请参考以下文章

java三种调用方式(同步调用/回调/异步调用)

LINUX系统调用

引用调用 vs 复制调用调用

RPC 调用和 HTTP 调用的区别

js方法调用

深入理解Java虚拟机——方法调用(解析调用)