ViewDidLoad (and loadView) does not start after the view controller is inserted into the navigation controller

viewController view does not load immediately after that viewController is inserted into the navigation controller.

This is my piece of code.

- (void)myMethodInClassA { // window 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 view is NOT loaded } 

When I call myMethodInClassA , myVC viewDidLoad is called AFTER this method returns. I expected the myVC view to be loaded immediately after calling the navigation controller pushViewController:animated: and before returning myMethodInClassA.

When exactly is the view of the controller viewed? Apple's documentation just says that it loads on first access. This is a bit ambiguous. Why is the navigation controller pushViewController: missing?

ps sorry for the initial ambiguous question.

+4
source share
5 answers

Pushing a view controller (VC) onto the navigation controller stack makes VC the child view controller of the navigation controller (which is the container controller). Creating such a parent-child relationship is a separate step that does not immediately load the child VC view. Rather, the VC container loads the view later. I believe that there is no explicit specification of what β€œlater” means - it will usually be when the VC container has decided that it is time to integrate the child VC view into the hierarchy of viewing the VC container. But basically it just happens at the discretion of the VC container implementation.

At the same time, anyone can make VC view load with simple access to the VC view property. For example, in your code you can add this line

 myVC.view; 

which launches loadView and then viewDidLoad in MyViewController .

However, in your case, if MyViewController should respond to an event associated with the VC container, then it would be better to override one (or both?) MyViewController following methods in MyViewController :

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

However, you need to know that willMoveToParentViewController and didMoveToParentViewController also called when MyViewController unloaded from its parent navigation controller stack. You may find this to be true by checking the parent argument for nil .

+8
source

As indicated above, viewDidLoad is called once when you click on a view, you may want to make your own material in viewWillAppear or viewDidAppear.

+1
source

(Swift 2) Since this question has no accepted answer ...

What I ended up with was creating convenience initialization in the child view controller:

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

and in parentViewController viewDidLoad () :

 let commentsView = CommentsViewController() self.addChildViewController(commentsView) self.momentsScrollView.addSubview(commentsView.view) commentsView.didMoveToParentViewController(self) 
+1
source

Ya, if this ViewController is already running on the navigationController stack, then the ViewDidLoad method will no longer be called. The first time you click this ViewController, viewDidLoad will be called. Therefore, if you need each of your functions to be executed every time, and then to execute it in viewWillAppear mode, because it will be called every time you click your viewController.

Hope this helps you.

0
source

do you click on the view controller for the first tym? If YES, then only the viewDidLoad () of the controller will be called, and if it has already been pressed, and this is not the first line, viewWillAppear () will be called. (or) if you create a new instance, every time you click on it, then viewDidLoad () is called.

0
source

Source: https://habr.com/ru/post/1483710/


All Articles