instantiateViewControllerWithIdentifier seems to call viewdidload
Asked Answered
H

4

9

I am trying to push a ViewController programmatically into a navigation controller, And I'm using my storyboard to create it.

here is my code :

+ (void) pushViewController:(NSString *) identifier ForItems:(NSMutableArray *) items sender:(UIViewController *) sender {
    GenericViewController *viewController = (GenericViewController *)[sender.storyboard instantiateViewControllerWithIdentifier:identifier];

    viewController.items = [[NSMutableArray alloc] init];
    [viewController.items removeAllObjects];
    [viewController.items addObject:[[NSMutableArray alloc] init]];
    [viewController.items[0] addObjectsFromArray:items];

    [sender.navigationController pushViewController:viewController animated:YES];
}

In GenericViewController viewDidLoad I'm using my items. Thanks to some break points I've seen that GenericViewController viewDidLoad juste after the instantiateViewControllerWithIdentifier with an items equal to nil.

I thought that MyViewController viewDidLoad is called during the pushViewController method.

Any idea why viewDidLoad is called during instantiateViewControllerWithIdentifier ?

---Update :---

Here my viewDidLoad

- (void)viewDidLoad
{
    for (MyItem *currentItem in self.items[0]) {
        [Do Something]
    }

    [super viewDidLoad];


    [...]
}

self.items is nil. so nothing is done.

Hanuman answered 5/5, 2014 at 13:57 Comment(4)
put the complete code please..what is myItem and the viewDidLoad method..the problem is not this..cause when you initiate an object, it is alive.Amend
You need to provide more information. Show the whole method where you use instantiateViewControllerWithIdentifier:. The method, instantiateViewControllerWithIdentifier:, will not cause viewDidLoad to be called, so something else is going on.Pyroligneous
thank you @Pyroligneous I am pretty sure instantiateViewControllerWithIdentifier do not call viewDidLoad. I update my code, I'm using a static manager to instanciate and push my new viewControllerHanuman
I still don't see anything in your posted code that would cause viewDidLoad to be called before you do the push. Do you have any segues setup to GenericViewController? Is GenericViewController a stand alone controller (not embedded in anything)?Pyroligneous
V
8

To anyone that might still have the same problem.

I had a similar situation and solved it by just calling loadViewIfNeeded().

let sb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let controller = sb.instantiateViewControllerWithIdentifier("LoadingView") as! LoadingViewController
controller.loadViewIfNeeded()

I could then access everything inside the view.

Vereen answered 18/3, 2016 at 14:5 Comment(1)
As documentation says, loadView() should never be called directly. developer.apple.com/reference/uikit/uiviewcontroller/…Butanone
L
3

You can use [vc loadViewIfNeeded] in Objective-C or vc.loadViewIfNeeded() in Swift.

apple: loadViewIfNeeded

Lohse answered 24/12, 2016 at 12:18 Comment(0)
D
1

See: https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidLoad

viewDidLoad is called when the controller's view is loaded into memory.

viewWillAppear Notifies the view controller that its view is about to be added to a view hierarchy. I think this is when [self.navigationController pushViewController:viewController animated:YES]; is called.

viewDidAppear Notifies the view controller that its view was added to a view hierarchy. This is when MyViewController is added into navigationController.

Dneprodzerzhinsk answered 5/5, 2014 at 14:14 Comment(1)
it make sense, but so SO questions indicate that it is a good way to pass properties to a view controller. (https://mcmap.net/q/1315251/-how-and-where-would-you-use-instantiateviewcontrollerwithidentifier, https://mcmap.net/q/1315252/-passing-property-value-using-instantiateviewcontrollerwithidentifier-with-storyboards)Hanuman
V
0

As voyage11 mentioned, viewDidLoad is called when the controller's view is loaded into memory, although someone has pointed out that this does not necessarily occur during the instantiateViewControllerWithIdentifier method.

Following your example code, I'd put the loop in the viewWillAppear method:

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];  // good practice to call the super
    for (MyItem *currentItem in self.items[0]) {
        [Do Something]
    }
}
Vicious answered 5/5, 2014 at 14:22 Comment(2)
You initial statement is incorrect -- viewDidLoad will not be called just by instantiating a view controller.Pyroligneous
Good point. I've updated my answer to remove that implication.Vicious

© 2022 - 2024 — McMap. All rights reserved.