Introduction:
View Controllers have a "lifecycle" from loading to unloading, and we must override its delegate methods according to our requirements.
1.The life cycle starts with alloc and initialization:
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)aBundle;
This is the UIViewController's designated initializer. The UIViewController attempts to get its view from the specified .xib file called nibName. If nibName is nil, it uses the name of the class as the nibName (MyViewController.xib). The bundle allows you to specify one of a number of different .xib files (localization). Passing nil for aBundle basically means "look in the Resources folder from Xcode". Initializing UIViewController with init is very common, it means nibName is nil & aBundle is nil. Can I build a UIViewController's view in code (i.e. w/o a .xib)? Yes. If no .xib is found using Mechanism above, UIViewController will call "(void)loadView" on itself. loadView's implementation MUST set the view property in the UIViewController. Don't implement loadView and specify a .xib file (it's undefined what this would mean).
2. viewDidLoad is called after the UIViewController is initialized.
- (void)viewDidLoad;
The viewDidLoad method is only called when the view is first loaded from the Nib file. If the view was already loaded and you push the view again it will not fire again. viewDidLoad is things you must do once. Whenever I'm adding controls to a view that should appear together with the view, right away, I put it in the ViewDidLoad method. Basically this method is called whenever the view was loaded into memory. So for example, if my view is a form with 3 labels, I would add the labels here; the view will never exist without those forms.
3. Just before the view appears on screen, viewWillAppear is called.
- (void)viewWillAppear:(BOOL)animated; Your view will probably only be "loaded" once, but it might appear and disappear a lot. So don't put something in this method that really should be in viewDidLoad. Otherwise, you might be doing something over and over unnecessarily. Use this to optimize performance by waiting until this method (i.e. just before the view appears) to kick off an expensive operation (might have to use a spinning "loading" icon though).
4. viewWillDisappear will be called when you will disappear off screen
- (void)viewWillDisappear:(BOOL)animated { } [superviewWillDisappear:animated];
//callthisinalltheviewWill/Didmethods // let's be nice to the user and remember the scroll position they were at ... [selfrememberScrollPosition]; //we'llhavetoimplementthis // do some other clean up now that we've been removed from the screen [self saveDataToPermanentStore]; // but be careful not to do anything time-consuming here, or the app will be sluggish // maybe even kick off a thread to do what needs done here
5. There are also "did" versions of both of these method:
- (void)viewDidAppear:(BOOL)animated; - (void)viewDidDisappear:(BOOL)animated;
6. In low-memory situations, viewDidUnload is called.
Be sure to release your outlets (or other data tied with the view and its subviews).
7. Now for the device rotation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)anOrientation { return (anOrientation == UIInterfaceOrientationPortrait) || (anOrientation == UIInterfaceOrientationPortraitUpsideDown);}
The default is to only allow UIInterfaceOrientationPortrait. This UIViewController's view is allowed to flip around if the device is turned upside down. There is also UIInterfaceOrientationLandscapeLeft and Right. It is certainly nice to return YES from this method for as many as possible orientations. But make sure that your view can draw itself "wide and not-tall" as well as "tall and not- wide" if you are going to return YES for the landscape orientations.
View Controller When rotation actually happens: (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)anOrientation duration: (NSTimeInterval)seconds; - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)anOrientation; @property UIInterfaceOrientation interfaceOrientation; The property will have the current orientation when each of the above is called. Stop doing anything costly (e.g. an animation maybe?) in will and resume it in did. The best way to handle rotations is to design your view to layout its subviews properly (i.e. set their frames) no matter what the aspect ratio of the view is. Interface Builder can let you set "struts and springs" to help with layout flexibility. Or the UIView method layoutSubviews can be overridden to do this (outside this course's scope).