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

时间:2013-05-31 03:11:55

标签: ios uiviewcontroller uinavigationcontroller viewdidload

在将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
}

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

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

P.S。抱歉最初的含糊不清的问题。

6 个答案:

答案 0 :(得分:8)

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

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

myVC.view;

会在loadView中触发viewDidLoad然后MyViewController

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

MyViewController

但是,您需要注意,当- (void) willMoveToParentViewController:(UIViewController*)parent { // write your code here } - (void) didMoveToParentViewController:(UIViewController*)parent { // write your code here } 从其父导航控制器的堆栈中弹出时,也会调用willMoveToParentViewControllerdidMoveToParentViewController。您可以通过检查MyViewController的{​​{1}}参数来检测到这种情况。

答案 1 :(得分:2)

(斯威夫特2) 由于这个问题没有得到接受的答案......

我最终做的是在子视图控制器上创建一个便利初始化:

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)

答案 2 :(得分:1)

如上所述,当推送视图时,viewDidLoad会被调用一次,您可能想在viewWillAppear或viewDidAppear中执行您的操作。

答案 3 :(得分:0)

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

希望它对你有所帮助。

答案 4 :(得分:0)

你是否推动了第一个tym的视图控制器?如果是,则只调用控制器的viewDidLoad(),如果它已经被推,这不是第一个tyn,那么将调用viewWillAppear()。(或)如果您正在创建一个新实例,则每次推送它都会调用viewDidLoad()。

答案 5 :(得分:0)