iPhone Application Development – View Controllers
In this article, we’ll examine the View Controller and its lifecycle.
What is a View Controller?
View Controllers perform your application logic and help in managing the views and the data in your application.
The base class for all the controllers in iOS is UIViewController
. So, the custom controllers that we create in our application should also be a subclass of UIViewController
.
UIViewController
will always have a reference to the top-level UIView
.
@property(nonatomic,retain) UIView *view;
You can find the above line in the header file of UIViewController
. Press cmd
and then click on UIViewController
in XCode to access its header file.
Special View Controllers
There are certain special view controllers in iOS SDK that manages a collection of controllers. We can use these controllers to create standard iOS User interfaces.
UINavigationController
Manages a navigational or hierarchical flow of MVCs. Controllers are arranged in the form of a stack.
Example: Settings application in iPhone.
When you press any settings option it navigates to the next page. Internally you are pushing a view controller onto the stack.
UITabBarController
Manages a collection of MVCs. Tabs will be displayed in the bottom of the screen and each tab corresponds to one MVC. Displays only one MVC at a time.
Example: Photos application
Check on the tabs at the bottom of the screen.
UISplitViewController
Manages two MVCs at a time. It contains a master and a detail view controller. Screen is divided into two portions to display the two controllers. This controller is designed only for iPad.
Example: iPad Settings application
View Controller life cycle
The following methods form the lifecycle of the View Controller.
The life cycle starts with the following initialization method.
initWithNibName:bundle
- Default initializer of the view controller.
NSBundle
object denotes the location in the file system where the application resources like image files, nib files, executable, localization files etc., are stored.nibName
represents the interface builder file(.xib) corresponding to the controller.Bundle
represents the location of the nib file- So the
UIViewcontroller
tries to get the view from the nib or xib file. If the nib name is nil, it uses the name of the controller as the nib name and if the bundle is nil it looks for the nib file in the resources folder.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self != nil)
{
// Any other initialization
}
return self;
}
Loadview
The View controller calls this method when the view property is requested and it is nil.
The default implementation of load view does any one of the following
- Loads the view from the storyboard or nib file
- If there is no nib file or storyboard it crates an empty
UIView
object and assigns it to the view property of the view controller
We can override the load view and set our own custom views as the view of the view controller. But don’t call super method from the overridden load view method, as the super class will execute the default implementation that is not required.
- (void)loadView
{
// Set your custom view
CustomView *cView = [[CustomView alloc] initWithFrame:CGRectZero];
cView.backgroundColor = [UIColor whiteColor];
self.view = cView;
}
viewDidLoad
- After instantiation and the outlets are set,
viewDidLoad
method is called. - As a thumb rule, we will give super class a chance to do any additional set up in all the life cycle methods given below.
- This is where your entire initial set up code is written.
- Remember that the geometry of the view is not set in this method. The geometry of the view is taken from the storyboard or nib file in this method. But the device and its actual orientation could be different. So don’t do geometry related stuff here.
- It is called only once unless and until your view gets deallocated.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
ViewWillAppear
This is called just before the view appears on the screen. The animated variable specifies whether you want the view to appear instantly or in an animated manner.
Your view may appear and disappear so many times in your application. So this method is called every time your view is about to appear on the screen.
Geometry related initialization and code to update the view based on the changes in other screens or data changes can be done here.
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
}
ViewWillDisappear
This is called just before the view disappears from the screen.
Code to save the data in the view or save the view state can be written here. Clean up code if required can also be done here.
Remember not to put any time consuming or expensive operations in all these methods
-(void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:YES];
}
ViewDidAppear and viewDidDisappear
As the name indicates, these two methods are called just after the view appears or disappears from the screen
- (void)viewDidAppear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
Autorotation
When the device is rotated, the top-level view controller should also have its bounds reoriented to the device orientation.
The following steps could accomplish this.
The view controller should return YES
in the shouldAutorotate
method.
-(BOOL) shouldAutorotate
{
return YES;
}
The supportedOrientations
should be defined in the view controller
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
The application should also allow rotation to the orientations that can be specified in the info.plist
file
Whenever the rotation will or did happen the following notifications are triggered
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
We can specify the layout of the sub views in this method. This could also be done through Autolayout technique, which would help us in specifying the layout of the sub views with the help of layout constraints.
didReceiveMemoryWarning
When the application runs out of memory, the view controller will be notified with the help of this method and this method will be triggered.
If you are using too many images or media files in your application and if all of these file are in memory this could happen. If these files are not being used and if they can be recreated we should set the pointer to these files as nil.
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Conclusion
Now you have an understanding of View Controllers, we will discuss some examples in my next article.