Have patience with me, I'm still learning Cocoa Touch. Other -viewDidLoad not being called question was unrelated to my issue, I did search.
I have FooViewController
, a UIViewController
subclass. FooViewController.xib has its File's Owner set to FooViewController. Additionally, I have Main
, whose App Delegate is MyApplication
and whose File's Owner is UIApplication
. My primary nib is set to Main.
I am able to make the view appear on the screen, using this flow (code snipped for brevity):
UIWindow *main;
-(void)applicationDidFinishLaunching:(UIApplication*)application {
[self showFooViewController];
[main makeKeyAndVisible];
}
-(void)showFooViewController {
fooViewController = [[FooViewController alloc] init];
if(![[NSBundle mainBundle] loadNibNamed:@"FooViewController" owner:fooViewController options:nil]) {
DebugF(@"Failed to load FooViewController");
return;
}
// Add the view and put it in place
UIView *view = [fooViewController view];
CGRect cur = [view frame];
cur.origin = CGPointMake(0.0f, 20.0f);
[view setFrame:cur];
[main addSubview:[fooViewController view]];
}
However, this message is not being sent to FooViewController
:
- (void) viewDidLoad {
DebugF(@"Hello!");
}
Total silence in gdb's output.
I've seen other Cocoa tutorials that show Instances and such in IB's document view, but I do not see these options in mine. Am I supposed to be instantiating fooViewController in the Nib? Did I miss a connection? In FooViewController.xib, File's Owner view is connected to the view in the Nib.
I'm sure this is a simple solution, and I have wandered down the wrong path. Halp!
And I've answered my own question, so this may help future folks. Since I see viewDidLoad has, as its three top Googles in my suggest, "viewDidLoad not called", "viewDidLoad not getting called", and "viewDidLoad not firing", I imagine this is a usual mistake...
Changing:
To:
Fixed the problem. Obviously a mistake in how I'm using Cocoa.
I have not found documentation to back up the following, but this is what I've deduced by experiment / experience:
The
viewDidLoad
method is expected be called immediately afterloadView
is called, and it's up to whomever callsloadView
to supply the extra call toviewDidLoad
.In some cases, the SDK will handle this behavior for you. Suppose you have a subclass of
UIViewController
calledMyViewController
; then:myViewController.view
before you callloadView
, then the superclass accessor is smart enough to callloadView
for you, andviewDidLoad
immediately thereafter.As a result, if your code looks like this:
then both
loadView
andviewDidLoad
will be called on your behalf.However, if your code looks like this:
then the
view
getter can see you've already loaded the view, and it assumes you also calledviewDidLoad
as well - so it doesn't call either. Ironically, the extra function call here preventsviewDidLoad
from getting called.I have had this same problem twice. The first time, I forgot to connect the view of UITableViewController to the actual UITableView in interface builder. The second time, I forgot to make
awakeFromNib
call itself in the superclass.