将视图控制器推入导航控制器后,不会触发viewDidLoad(和loadView)

min*_*end 4 uiviewcontroller uinavigationcontroller viewdidload ios

在将viewController推入导航控制器之后,viewController的视图不会被加载.

这是我的代码片段.

- (void)myMethodInClassA {
    // window's root view controller is navigation controller
    UINavigationController *naviCtrl = (UINavigationController*)[UIApplication sharedApplication].keyWindow.rootViewController;
    MyViewController *myVC = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
    [naviCtrl pushViewController:myVC animated:NO];

    // at this point, myVC's view is NOT loaded
}
Run Code Online (Sandbox Code Playgroud)

当我打电话时myMethodInClassA,myVC viewDidLoad被称为AFTER,该方法返回.我希望在pushViewController:animated:调用导航控制器之后和myMethodInClassA返回之前加载myVC的视图.

何时加载了视图控制器的视图?Apple的文档只是说它在首次访问时已加载.这有点模棱两可.为什么导航控制器的pushViewController:访问视图控制器没有视图?

抱歉抱歉最初的模棱两可的问题.

her*_*ube 8

将视图控制器(VC)推送到导航控制器的堆栈使VC成为导航控制器(它是容器视图控制器)的子视图控制器.创建这样的子父关系是一个独特的步骤,它不会立即加载子VC的视图.而是容器VC稍后加载视图.我认为没有明确规定"后来"意味着什么 - 通常是当容器VC决定将子VC的视图集成到容器VC的视图层次结构中的时候.但基本上它只是由容器VC的实施自行决定.

话虽这么说,任何人都可以通过简单地访问VC的view属性来强制加载VC的视图.例如,在您的代码中,您可以添加此行

myVC.view;
Run Code Online (Sandbox Code Playgroud)

这将触发loadView然后viewDidLoad进入MyViewController.

但是,在您的情况下,如果MyViewController需要对与容器VC关联的事件作出反应,那么最好覆盖以下方法中的一个(或两个?)MyViewController:

- (void) willMoveToParentViewController:(UIViewController*)parent
{
    // write your code here
}

- (void) didMoveToParentViewController:(UIViewController*)parent
{
    // write your code here
}
Run Code Online (Sandbox Code Playgroud)

但是,您需要注意,当从其父导航控制器的堆栈中弹出时willMoveToParentViewController,didMoveToParentViewController也会调用MyViewController它.您可以通过检查parent参数来检测是否是这种情况nil.