views:

290

answers:

1

I have a somewhat complex view that I put together in a separate (View-based template) project (the View Controller was represented with orange icon in MainWindow.xib). It's far enough along now that I've decided to move it into another project where it will be managed by a Navigation Controller. It is called from UINavigationController's fairly straightforward pushViewController: animated: method.

MyViewController has a corresponding nib file (perhaps some of my confusion is the class & nib are nearly identically named with only suffixes .m, .h, & .xib being different). When this was the initial view on launch in the initial project both awakeFromNib and initWithCoder would be called when it was instantiated. Now only viewDidLoad seems to get called.

I'm confused as to what/why there is such a difference?!? I've found some other threads on S.O. that are related but they still leave me scratching my head with answers like: "awakeFromNib is called when the controller itself is unarchived from a nib. viewDidLoad is called when the view is created/unarchived. This distinction is especially important when the controller's view is stored in a separate nib file."

The distinction seems to be dependent upon what, exacty, is being unarchived the View or the ViewController. So if the ViewController is being instantiated and pushed then I should only expect viewDidLoad to be called? and on the other hand if my ViewController has an IBOutlet (and an object VC object representing it that has been dragged into my Nib) then I can expect initWithCoder and awakeFromNib to both get called?

Can someone please help set me straight? Seems like it's more difficult to reuse these views/controllers if different methods are arbitrarily called in very specific circumstances...or, as is certainly the case, this is exactly why they're called in, rather, very specific circumstances..i just don't fully understand the delineation between each of the various methods yet.

Anyone care to help set me straight?

+1  A: 

The distinction seems to be dependent upon what, exacty, is being unarchived the View or the ViewController. So if the ViewController is being instantiated and pushed then I should only expect viewDidLoad to be called? and on the other hand if my ViewController has an IBOutlet (and an object VC object representing it that has been dragged into my Nib) then I can expect initWithCoder and awakeFromNib to both get called?

This is where you're going astray. It's not whether or not the ViewController has an IBOutlet. It's whether or not the ViewController is instantiated in a NIB that determines if -awakeFromNIB is called.

From your description, I take it somewhere in your code you have something like this:

MyViewController *vc = [[MyViewController alloc] init]; // (or initWithNibName:bundle:)
[navController pushViewController:vc animated:YES];
[vc release];

If so, then the NIB is not instantiating MyViewController. Your code is. As so -awakeFromNib is not going to be called. You're not awoken from a NIB.

What you may have meant to do is to expand the Navigation Controller in your NIB (switch to the list-view; the middle button in the View Mode set of buttons in the upper left). There you'll see the root View Controller. By default it's a UIViewController. If you wanted the root controller to be MyViewController, you should change its class. In that case you'd get an -awakeFromNib call because it would be the NIB that created this object. You should then of course get rid of any code that's also instantiating it and putting it on the NavController.

Rob Napier
It's actually being called by: MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; though what you say makes sense...though wonder if it's still applicable in my case?
Meltemi
Yes, it's exactly the same. Note the comment in the first line of code above. initWithNibName:bundle: is the same thing in this case as init.
Rob Napier
Indeed... thanks for pointing that out I didn't scroll right..
Meltemi