A UIViewController controls a given UIView.
A UIViewController has a loadView method that can be overridden to set its UIView:
- (void)loadView
{
CGRect frame = [[UIScreen mainScreen] bounds];
MyView *view = [[MyView alloc] initWithFrame:frame];
[self setView:view];
}
Set the controller as the root one in the App Delegate file:
MyViewController *viewController = [[MyViewController alloc] init];
[[self window] setRootViewController:viewController];
The designated initializer of UIViewController is initWithNibName:bundle:. If you pass in nil for both arguments, an XIB file with the same name as the class will be loaded, and its application bundle with be searched.
Typically, the name of a UIViewController will be the same as the name of the XIB file. So you only need to call:
MyViewController *viewController = [[MyViewController] alloc] init];
MyViewController *viewController = [[MyViewController] alloc] initWithNibName:nil bundle:nil];
Views are loaded only as needed. If the system is running low on memory and the view is not on the screen, the view controller will destroy the view.
Override viewDidLoad to perform any actions after the view loads:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog("@"Loaded view!");
}
This is only triggered the first time the view loads.
Every UIViewController has a view method like this:
- (UIView *)view
{
if ([self isViewLoaded] == NO)
{
[self loadView];
[self viewDidLoad];
}
return view;
}
Any subviews referenced in the UIViewController will continue to exist even if the view is destroyed. These references should be destroyed in viewDidUnload:
- (void)viewDidUnload
{
[super viewDidUnload];
NSLog(@"Unloading subviews);
myLabel = nil;
}
The alternative is to use a weak reference:
@interface MyViewController : UIViewController
{
__weak IBOutlet UILabel *myLabel;
}
Declare IBOutlets as weak references to prevent memory leaks. Don't do this for top-level objects such as the controller's view, which need to stay in place.
UIViewController also has the following methods: