使用 UINavigationController 时,不会调用我的控制器的 viewWillAppear 或 viewDidAppear 方法 [英] When using a UINavigationController the viewWillAppear or viewDidAppear methods of my controller are not called

查看:25
本文介绍了使用 UINavigationController 时,不会调用我的控制器的 viewWillAppear 或 viewDidAppear 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是音调.

  • 我有一个 UIViewController 子类,它在 viewWillAppear 和 viewDidAppear 方法中做了一些事情.
  • 我想将此视图控制器嵌套在 UINavigationViewController 中.
  • 根据视图层次结构的复杂性,我的控制器的两个方法 viewWillAppearviewDidAppear 可能不会被调用.
  • I have a UIViewController subclass which does something in its viewWillAppear and viewDidAppear methods.
  • I want to nest this view controller in a UINavigationViewController.
  • Depending on the view hierarchy complexity the two methods viewWillAppear and viewDidAppear of my controller may not be called.

那么我应该怎么做才能确保无论我的视图层次结构如何都始终调用这两个方法?

What should I do then to make sure these two methods are always called regardless of my view hierarchy?

复杂"视图层次结构示例:

Example of a "complex" view hierarchy:

UIViewController subclass containing a UITabBarController
     |_ Each tab containing a UINavigationViewController
         |_ Each UINavigationController controller containing a custom UIViewController

当您将 TabBarController 显示为模式视图时,将调用 TabBarController 的 viewWillAppearviewDidAppear 方法,但不会调用嵌套在 UINavigationViewControllers 下的自定义 UIViewControllers 的方法.p>

When you present the TabBarController as a modal view the viewWillAppear and viewDidAppear methods of the TabBarController are called but not those of the custom UIViewControllers nested under the UINavigationViewControllers.

推荐答案

注意:这是在 2013 年编写的.现在 iOS 处理视图层次结构的方式发生了变化,这可能会使这个解决方案变得无用和/或危险.所以使用风险自负.

原答案当在 UINavigationController 下嵌套自定义 UIViewController 时,可能不会调用自定义 viewController 的 viewWillAppear 和 viewDidAppear 方法,具体取决于视图控制器层次结构的复杂性(想想模式视图、选项卡视图控制器内的导航控制器......).因此,如果您发现自己处于这种情况下,您可以做些什么来确保调用这两个方法?

Original Answer When nesting a custom UIViewController under a UINavigationController the methods viewWillAppear and viewDidAppear of the custom viewController may not be called depending on the complexity of your view controller hierarchy (think modal views, navigation controller inside tab view controller...). So if you find yourself in this situation what can you do to ensure these two methods are called?

答案...

这是一种非常优雅的实现方法,因为它不依赖于关于导航控制器何时加载控制器的任何假设.

This is a very elegant method to implement for it does not rely on any assumptions regarding when the controller will be loaded by the navigation controller.

有两种方法可用:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated

下面是代码的变化方式.

Here is how the code would change.

您需要声明您的 CustomViewController 实现了 UINavigationControllerDelegate 协议:

You need to declare that your CustomViewController implements the UINavigationControllerDelegate protocol:

@interface CustomViewController : UIViewController <UINavigationControllerDelegate>

您需要将您的 CustomViewController 设置为您初始化它的 UINavigationController 的委托.

You need to set your CustomViewController as the delegate of the UINavigationController where you initialize it.

最后,您还必须将 UINavigationControllerDelegate 方法的自定义实现添加到您的 CustomViewController 类实现中.例如,您可以实现 navigationController:willShowViewController:animated: 方法,以便:

Last you must also add your custom implementation of the UINavigationControllerDelegate methods to your CustomViewController class implementation. For instance you can implement the navigationController:willShowViewController:animated: method so that:

  • 当 UINavigationController 即将显示视图控制器本身时,您的 viewWillAppear 方法将被调用
  • 当 UINavigationController 即将显示另一个视图控制器时,UINavigationController 的委托被设置为另一个视图控制器,前提是该视图控制器实现了 UINavigationViewControllerDelegate 方法.

列表项

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if ([viewController isEqual:self]) {
            [viewController viewWillAppear:animated];
    } else if ([viewController conformsToProtocol:@protocol(UINavigationControllerDelegate)]){
            // Set the navigation controller delegate to the passed-in view controller and call the UINavigationViewControllerDelegate method on the new delegate.
            [navigationController setDelegate:(id<UINavigationControllerDelegate>)viewController];
            [[navigationController delegate] navigationController:navigationController willShowViewController:viewController animated:YES];
    }
}

navigationController:didShowViewController:animated:可以简单实现如下:

- (void)navigationController:(UINavigationController *)navigationController 
       didShowViewController:(UIViewController *)viewController 
                    animated:(BOOL)animated
{
    if ([viewController isEqual:self]) {
        [self viewDidAppear:animated];
    }
}

这种方法的好处实际上是您完全依赖 UINavigationViewController 应该工作的方式,并且您可以在正确的时间进行调用.它还允许您在调用 viewWillAppear 方法之前在导航控制器层次结构中上下移动时传递委托.

The benefit of this approach is really that you solely rely on the way the UINavigationViewController is supposed to work and you make your calls just at the right time. It also allows you to pass the delegation around as you move up and down the navigation controller hierarchy right before the viewWillAppear method is called.

同样,对于简单的层次结构,这可能不是必需的.但是,如果您发现自己的 viewWillAppearviewDidAppear 方法没有被调用,那么您现在知道该怎么做了...

Again for simple hierarchy this may not be required. But if you ever find yourself in a situation where your viewWillAppear and viewDidAppear methods are not called you now know what to do...

这篇关于使用 UINavigationController 时,不会调用我的控制器的 viewWillAppear 或 viewDidAppear 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆