tags:

views:

5627

answers:

2

This should be straight forward for a guru. I don't have any code really written out, just a couple of controllers and a custom UIView. All connected through nibs. The app loads without crashing, yet I can't see my NSLog() hit from my custom UIView.

My application delegate has default template code which calls for a class of mine called TabAnimationController. TabAnimationViewController has its view set to TabView. I made sure that in TabAnimationViewController's NIB that File's owner is set to TabAnimationViewController and that my instance of UIView has its class set to TabView.

In TabView.m I'm trying to see how NSLog is going to hit, and it's not showing up at all.

- (void)loadView {
 NSLog(@"calling loadView");
}

- (id)initWithFrame:(CGRect)frame {
NSLog(@"Calling initWithFrame:");
    return self;
}

Strange. I'm not sure why even after proper IB connections that my NSLog will not show up. Only anything put into drawRect: will invoke. Why isn't initWithFrame or loadView ever get hit? What if I want to customize this view programmatically?

+3  A: 

First of all, when a view is dehydrated from nib file, instead of initWithFrame, initWithCoder is invoked. So you need to implement your initialization in initWithCoder as well. (It may be a good idea to keep the initWithFrame initialization as well, if you anticipate programmatically creating your TabView instead of hooking up in the IB. Just refactor your initialization to another method and call it from both implementations.)

Also in your initialization code above you must always call the super class's initialization. There is a boiler plate pattern all custom classes use in their init implementation for that:

if (self = [super initXXX]) { do your initialization } 
return self;

Second, loadView which is actually a UIViewController method and not a UIView method is invoked only if the view outlet of the controller is nil.

Unless you are composing your view yourself programmatically using your controller, you do not need to override loadView. Instead you should override viewDidLoad, which is called after the view is loaded, to do additional initialization.

keremk
I would say you *must* call the super init, not should. There was a wonderful song about this at the last WWDC: http://www.youtube.com/watch?v=ajlESsRXqmM
Kevin Ballard
Selector name wrong. Last paragraph should read, "Instead, you should override viewDidLoad, ..."
benzado
Thanks benzado. I just updated the last paragraph.
keremk
A: 

The simplest way to get this up and running is simply to use the "View based Application" template when you create a new project. It sets up everything you need to start with.

But, in short, you're looking at the wrong methods. First, you shouldn't override loadView unless you're creating your view programatically. If it's loading from a XIB file look at the initWithNibName method.

You might also want to look at the viewDidLoad, viewWillAppear and viewDidAppear methods that are triggered, well, it's fairly obvious when!

Stephen Darlington