When I program without a nib, I am under the impression that I need to call loadView to initialize my view, like this:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nil bundle:nil]; if (self) { // Custom initialization [self loadView]; } return self; }
(I have set nibNameOrNil = nil, since there is not nib.)
Then, I set up the view, like this:
- (void) loadView { self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 367)]; [self viewDidLoad]; }
This is do everything else in viewDidLoad.
I'm still unsure if I am supposed to make the calls to loadView and viewDidLoad in this way. They are not getting called automatically.
What is confusing is in the documentation for the UIViewController class reference:
loadView Discussion
You should never call this method directly. The view controller calls this method when the view property is requested but is currently nil. If you create your views manually, you must override this method and use it to create your views. If you use Interface Builder to create your views and initialize the view controller—that is, you initialize the view using the initWithNibName:bundle: method, set the nibName and nibBundle properties directly, or create both your views and view controller in Interface Builder—then you must not override this method.
So, I don't understand how loadView gets called if I should never call it directly.
The default implementation of this method looks for valid nib information and uses that information to load the associated nib file. If no nib information is specified, the default implementation creates a plain UIView object and makes it the main view.
I don't understand how that works -- the creation of a pain UIView.
If you override this method in order to create your views manually, you should do so and assign the root view of your hierarchy to the view property. (The views you create should be unique instances and should not be shared with any other view controller object.) Your custom implementation of this method should not call super.
If you want to perform any additional initialization of your views, do so in the viewDidLoad method. In iOS 3.0 and later, you should also override the viewDidUnload method to release any references to the view or its contents.
Okay, so far it doesn't say how viewDidLoad is called. So for viewDidLoad:
viewDidLoad Discussion
This method is called after the view controller has loaded its associated views into memory. This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method. This method is most commonly used to perform additional initialization steps on views that are loaded from nib files.
Called by what?
Since These methods are not getting called automatically in my code, I am left to think that I have to call them myself. But I still don't get a clear understanding form the documentation that this is the right thing to do.
loadView is the method that actually sets up your view (sets up all the outlets, including self. view). viewDidLoad you can figure out by its name. It's a delegate method called after the view has been loaded (all the outlets have been set) that just notifies the controller that it can now start using the outlets.
viewDidLoad is the method that is called once the MainView of a ViewController has been loaded. This is called after loadView is called.In the image you can see the MainView and other views within it.
Use viewDidLoad( ), which is called AFTER loadView( ) has completed its job and the UIView is ready to be displayed. viewDidLoad( ) allows you to initialize properties of the view/viewController object and finalize them before viewWillAppear( ) is called.
First UIViewController is alloc'ed by some other object, then init is immediately called (or some other init method, like initWithStyle). Only once the object is initialized would I expect it to call its own loadView function, after which the view, once loaded, calls the viewDidLoad delegate method.
As the documentation says, you should not call these methods yourself.
How this is meant to work is that UIKit's code will call your loadView method if and when it actually needs to present that controller's view hierarchy on screen.
Specifically, if any code attempts to read your view
property on your view controller, and that property is nil, then UIViewController's code will call the loadView
method. If you don't implement loadView
yourself, then the default implementation will fall back to attempting to load the view hierarchy from the nib.
This all happens automatically when you attempt to present your view controller and the view is nil. (This can happen multiple times while your app is running if your view controller has to unload its view in response to memory pressure, another behavior you get for 'free' and that you don't want to call yourself)
If these methods are not being called in your view controller, then there must be something wrong with how you are presenting this view controller, which is preventing the framework code in UIViewController from calling these methods. Post that code and someone can help you figure out that bug.
Before you attempt to fix that bug, though, you should remove these from your code:
[self loadView] [self viewDidLoad]
And then in your own implementation of viewDidLoad
, you will want to call the superclass' implementation with [super viewDidLoad]
Remember that in loadView
your only responsibility to set self.view to some valid view. That's it. UIKit code will then see that and call viewDidLoad
for you.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With