• Aucun résultat trouvé

Creating views for the view controllers

Dans le document Chapter 1. A Simple iPhone Application (Page 144-151)

Next, open CurrentTimeViewController.m and edit its init method:

- (id)init

{ [super initWithNibName:nil bundle:nil];

UITabBarItem *tbi = [self tabBarItem];

[tbi setTitle:@"Time"];

UIImage *i = [UIImage imageNamed:@"Time.png"];

[tbi setImage:i];

return self;

}

Now when you build and run the application, you will also see icons in the tab bar (Figure 7.8).

Figure 7.8. Tab bar items with labels and icons

Creating views for the view controllers

Now that you have a perfectly nice tab bar with two view controllers (and the two corresponding tab bar items), it’s time to give your view controllers views. There are two ways to do this:

• create the view programmatically

• create a XIB file

How do you know when to do one versus the other? Here’s a good rule-of-thumb:

if the view has no subviews, create it programmatically; if it has subviews, create a XIB file.

When the view needs to be created, the view controller is sent the message loadView. In HypnosisViewController, you are going to override this method so that it creates an instance of HypnosisView programmatically. When an instance of a UIViewController is instantiated, its view is not created right away.

A UIViewController’s view is created when it is placed in a view hierarchy (also known as “the first time it appears on screen”). Add the following method to HypnosisViewController.m:

- (void)loadView

{ HypnosisView *hv = [[HypnosisView alloc] initWithFrame:CGRectZero];

[hv setBackgroundColor:[UIColor whiteColor]];

[self setView:hv];

[hv release];

}

HypnosisViewController.m needs to know about the class HypnosisView. At this top of this file, import HypnosisView’s header file.

#import "HypnosisViewController.h"

#import "HypnosisView.h"

@implementation HypnosisViewController

We no longer want the background of the view to be orange; delete the following line from the viewDidLoad method in HypnosisViewController.m:

[[self view] setBackgroundColor:[UIColor orangeColor]];

Also, delete the similar line of code from the viewDidLoad method in CurrentTimeViewController.m.

[[self view] setBackgroundColor:[UIColor greenColor]];

(These two lines of code were just to test that the UITabBarController was working properly.)

Build and run the application. You should see a HypnosisView like the one in Figure 7.9.

Figure 7.9. HypnosisViewController

Double-click on CurrentTimeViewController.xib to open it in Interface Builder.

Double-click on the View object in the doc window to open it. From the Library, drop a button and a label on the View’s window. Make them both nearly as wide as the window. Change the title on the button to What time is it?. Change the label to ??? and set the alignment to centered (Figure 7.10).

Figure 7.10. Button and Label

See that icon labeled File’s Owner? It is a placeholder for an object to be supplied when the XIB file is read in. When the view controller loads the XIB file, it says

“Load the XIB named CurrentTimeViewController.xib, and I will act as File’s Owner.” Thus, you can know that the file’s owner is the view controller for this XIB. You know it is going to be an instance of CurrentTimeViewController, but Interface Builder does not.

In Xcode, add the necessary outlet and action to CurrentTimeViewController.h:

#import <UIKit/UIKit.h>

@interface CurrentTimeViewController : UIViewController {

IBOutlet UILabel *timeLabel;

}- (IBAction)showCurrentTime:(id)sender;

@end

Save that file and return to Interface Builder.

Control-click on File’s Owner to see its connection panel (Figure 7.11). Drag from timeLabel to the UILabel.

Figure 7.11. Connecting timeLabel and UILabel

The view controller has a pointer called view that needs to point to the entire view that is to be displayed. Notice that the view outlet is already connected to the instance of UIView in the doc window. (The template did this for you.)

Control-drag from the button to the File’s Owner (Figure 7.12). Choose the action showCurrentTime:.

Figure 7.12. Setting the showCurrentTime: action

Return to Xcode and open CurrentTimeViewController.m. In init, tell it the name of the XIB file it is to load. Also delete the line that sets the background color to green:

- (id)init

{ [super initWithNibName:@"CurrentTimeViewController"

bundle:nil];

UITabBarItem *tbi = [self tabBarItem];

[tbi setTitle:@"Time"];

UIImage *i = [UIImage imageNamed:@"Time.png"];

[tbi setImage:i];

return self;

}

Finally, implement the action method:

- (IBAction)showCurrentTime:(id)sender { NSDate *now = [NSDate date];

static NSDateFormatter *formatter = nil;

if (!formatter) {

formatter = [[NSDateFormatter alloc] init];

[formatter setTimeStyle:NSDateFormatterShortStyle];

}

[timeLabel setText:[formatter stringFromDate:now]];

}

Build and run the application. You will be able to switch back and forth between the two views. Clicking the button on the time view will display the current time.

viewWillAppear

UIViewController has several methods that get called at certain times:

viewWillAppear: when its view is about to be added to the window

viewDidAppear: when its view has been added to the window

viewWillDisappear: when its view is about to be dismissed, covered, or otherwise hidden from view

viewDidDisappear: when its view has been dismissed, covered, or otherwise hidden from view

These methods are useful because a view controller is only created once but usually gets displayed (and dismissed or hidden) several times. You often need a way to override the default behavior at these times in the life of view controller. For example, you may want to do some sort of initialization each time the view controller is moved on screen. Here you would use viewWillAppear:

or viewDidAppear:. Similarly, if you had a large data structure that you only need while the view controller is being displayed, you might want to do some clean-up each time the view controller is moved off screen. Then you would use viewWillDisappear: or viewDidDisappear:.

Note that these methods, as defined in UIViewController, do nothing. They are there so that your subclasses can override them.

- (void)viewWillAppear:(BOOL)animated;

- (void)viewDidAppear:(BOOL)animated;

- (void)viewWillDisappear:(BOOL)animated;

- (void)viewDidDisappear:(BOOL)animated;

Now let’s override viewWillAppear: to initialize the time label of the

CurrentTimeViewController to the current time each time it is displayed. In CurrentTimeViewController.m, make the following changes:

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated];

[self showCurrentTime:nil];

}

Build and run the application. Note that each time you return to the Time page, the time label is updated.

Dans le document Chapter 1. A Simple iPhone Application (Page 144-151)

Documents relatifs