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

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

问题描述

这是音调。


  • 我有一个UIViewController子类,它在viewWillAppear和viewDidAppear方法中做了一些事情。

  • 我想将此视图控制器嵌套在UINavigationViewController中。

  • 根据视图层次结构的复杂性,这两种方法 viewWillAppear 和 viewDidAppear 可能无法调用。

  • 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呈现为模态视图时, viewWillAppear viewDidAppear 方法调用TabBarController但不是嵌套在UINavigationViewControllers下的自定义UIViewControllers。

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时,方法viewWillAppear根据视图控制器层次结构的复杂性,可能无法调用自定义viewController的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 :动画:可以简单地实现如下:

And the navigationController:didShowViewController:animated: can be implemented simply as follows:

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

对于简单的层次结构,这可能不是需要。但如果您发现自己处于未调用 viewWillAppear viewDidAppear 方法的情况,您现在知道该怎么做......

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天全站免登陆