4

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
}

当我调用时,在该方法返回之后调用myMethodInClassAmyVC 。viewDidLoad我预计 myVC 的视图会在pushViewController:animated:调用导航控制器之后和 myMethodInClassA 返回之前加载。

何时加载视图控制器的视图?Apple 的文档只是说它是在第一次访问时加载的。这有点模棱两可。为什么导航控制器不能pushViewController:访问视图控制器的视图?

ps 很抱歉最初的模棱两可的问题。

4

6 回答 6

10

将视图控制器 (VC) 推送到导航控制器的堆栈上会使 VC 成为导航控制器的子视图控制器(它是容器视图控制器)。创建这样的子父关系是一个不同的步骤,它不会立即加载子 VC 的视图。而是容器 VC 稍后加载视图。我相信“稍后”的含义没有明确的规范——通常是在容器 VC 决定将子 VC 的视图集成到容器 VC 的视图层次结构中的时候。但基本上它只是由容器 VC 的实现自行决定。

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

myVC.view;

这将触发loadView然后viewDidLoadMyViewController.

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

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

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

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

于 2013-05-31T11:44:05.070 回答
2

(Swift 2)由于这个问题没有公认的答案......

我最终做的是在子视图控制器上创建一个方便的 init:

convenience init() {
    self.init(nibName: "ChildViewController", bundle: nil)
    //initializing the view Controller form specified NIB file
}

在 parentViewController 的viewDidLoad()中:

let commentsView = CommentsViewController()
self.addChildViewController(commentsView)
self.momentsScrollView.addSubview(commentsView.view)
commentsView.didMoveToParentViewController(self)
于 2016-01-29T22:57:23.553 回答
1

如上所述,viewDidLoad 在视图被推送时被调用一次,你可能想要在 viewWillAppear 或 viewDidAppear 中做你的事情。

于 2013-05-31T11:27:39.280 回答
0

是的,如果该 ViewController 已经被推送到 navigationController 堆栈中,则不会再次调用 ViewDidLoad 方法。第一次推送该 ViewController 时,将调用 viewDidLoad。因此,如果您需要每次都执行某些功能,请在 viewWillAppear 方法中实现它,因为每次推送 viewController 时都会调用它。

希望它可以帮助你。

于 2013-05-31T03:34:43.387 回答
0

你是在为第一个 tym 推送视图控制器吗?如果是,那么只会调用控制器的 viewDidLoad(),如果它已经被推送并且这不是第一个 tyn,那么 viewWillAppear () 将被调用。(或)如果你是每次你推送它都会创建一个新实例,然后 viewDidLoad() 将被调用。

于 2013-05-31T05:37:09.090 回答
0

我发现我必须打电话loadViewIfNeeded()

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621446-loadviewifneeded

于 2019-02-21T02:22:59.300 回答