Who should call viewDidLoad on programmatically loaded views?
When I need to load a view programmatically, I do the following:
MyController* myController = [[MyController alloc] init];
[[NSBundle mainBundle] loadNibNamed:@"myNib" owner:myController options:nil];
// use my controller here, eg. push it in the nav controller
This works fine, but my viewDidLoad controller never gets called. So I resorted to a manual call after the loadNibNamed call, but this is not entirely correct. I expected the framework to call viewDidLoad on my behalf. Is this the right way or am I missing something?
a source to share
I'm new to Stack Overflow, but I came across this question and discovered a couple of other methods to load the nib file that will ensure that the viewDidLoad method is called automatically. Ed Marty's answer is correct, but it requires you to go outside of the ViewController code to load the nib file, these two examples I offer here allow you to keep the code inside the ViewController implementation. Not necessarily the best ways, just different ones. If you know of any drawbacks to this please let me know your thoughts.
First, inside the initWithNibName: bundle: method of your UIViewController subclass, you can replace the call: self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
with something like this: self = [super initWithNibName:@"NameOfAlternateNibFile" bundle:nibBundleOrNil];
Or, you can accomplish what looks like the same thing:
[[NSBundle mainBundle] loadNibNamed:@"NameOfAlternateNibFile" owner:self options:nil];
[self setView:self.view]; //this line ensures that the viewDidLoad method is called
The key is in understanding what is written in the comments above for the function definition for $initWithNibName:bundle:
in the UIViewController.h file (see the bottom of my answer here, see italics).
The good thing about doing this using any of these methods is that viewDidLoad is called in any scenario.
Here are the directives listed in UIViewController.h:
Designated initializer. if you are a subclass of UIViewController, you must call the super implementation of this method even if you are not using an NIB. (As a convenience, the default init method will do this for you, and specify nil for both of these methods as arguments.) In the specified NIB, the proxy of the file owner must have a class set to your view controller subclass, with the output for the view hooked up to the main view ... if you call this method with nil nib name, then this class' -loadView method will try to load a NIB whose name matches your view controller class. If such a NIB actually exists, then you must either call -setView: before -view is calledor overrides the -loadView method to automatically configure your views. - (id) initWithNibName: (NSString *) nibNameOrNil bundle: (NSBundle *) nibBundleOrNil;
a source to share