Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Beginning iOS5 Development.pdf
Скачиваний:
7
Добавлен:
09.05.2015
Размер:
15.6 Mб
Скачать

150

CHAPTER 6: Multiview Applications

CAUTION: If you don’t see the switchViews: action as shown in Figure 6–14, check the spelling of your class file names. If you don’t get the name exactly right, things won’t match up.

Watch your spelling!

Save your nib file and move to the next step.

Building a View with a Toolbar

We now need to build a view to add to BIDSwitchViewController. As a reminder, this new view controller will be our root view controller—the controller that is in play when our application is launched. BIDSwitchViewController’s content view will consist of a toolbar that occupies the bottom of the screen. Its job is to switch between the blue view and the yellow view, so it will need a way for the user to change the views. For that, we’re going to use a toolbar with a button. Let’s build the toolbar view now.

Still in SwitchView.xib, in the nib’s dock, click the View icon to make the view appear in the editing window (if it wasn’t already there). This will also select the view. The view is an instance of UIView, and as you can see in Figure 6–15, it’s currently empty and quite dull. This is where we’ll start building our GUI.

Figure 6–15. The default view contained within our nib file, just waiting to be filled with interesting stuff!

www.it-ebooks.info

CHAPTER 6: Multiview Applications

151

Now, let’s add a toolbar to the bottom of the view. Grab a Toolbar from the library, drag it onto your view, and place it at the bottom, so that it looks like Figure 6–16.

Figure 6–16. We dragged a toolbar onto our view. Notice that the toolbar features a single button, labeled Item.

The toolbar features a single button. We’ll use that button to let the user switch between the different content views. Double-click the button, and change its title to Switch Views. Press the return key to commit your change.

Now, we can link the toolbar button to our action method. Before doing that, though, we should warn you: toolbar buttons aren’t like other iOS controls. They support only a single target action, and they trigger that action only at one well-defined moment—the equivalent of a touch up inside event on other iOS controls.

Selecting a toolbar button in Interface Builder can be tricky. Click the view so we are all starting in the same place. Now, single-click the toolbar button. Notice that this selects the toolbar, not the button. Click the button a second time. This should select the button itself. You can confirm you have the button selected by switching to the object attributes inspector ( 4) and making sure the top group name is Bar Button Item.

Once you have the Switch Views button selected, control-drag from it over to the File’s Owner icon, and select the switchViews: action. If the switchViews: action doesn’t pop up, and instead you see an outlet called delegate, you’ve most likely control-dragged

www.it-ebooks.info

152

CHAPTER 6: Multiview Applications

from the toolbar rather than the button. To fix it, just make sure you have the button rather than the toolbar selected, and then redo your control-drag.

TIP: Remember that you can always view the nib’s dock in list mode and use the disclosure

triangles to drill down through the hierarchy to get to any element in the view hierarchy.

We have one more thing to do in this nib, which is to connect BIDSwitchViewController’s view outlet to the view in the nib. The view outlet is inherited from the parent class, UIViewController, and gives the controller access to the view it controls. When we changed the underlying class of the file’s owner, the existing outlet connections were broken. So, we need to reestablish the connection from the controller to its view. Control-drag from the File’s Owner icon to the View icon, and select the view outlet to do that.

That’s all we need to do here, so save your nib file. Next, let’s get started implementing

BIDSwitchViewController.

Writing the Root View Controller

It’s time to write our root view controller. Its job is to switch between the blue view and the yellow view whenever the user clicks the Switch Views button.

In BIDSwitchViewController.m, first remove the comments around the viewDidLoad method. We’ll be replacing that method in a moment. You can delete the remaining commented-out methods provided by the template if you want to shorten the code.

Start by adding this code to the top of the file:

#import "BIDSwitchViewController.h"

#import "BIDYellowViewController.h" #import "BIDBlueViewController.h"

@implementation BIDSwitchViewController

@synthesize yellowViewController; @synthesize blueViewController;

.

.

.

Next, replace viewDidLoad with this version:

- (void)viewDidLoad

{

self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];

[self.view insertSubview:self.blueViewController.view atIndex:0];

[super viewDidLoad];

}

www.it-ebooks.info

CHAPTER 6: Multiview Applications

153

Now, add in the switchViews: method:

- (IBAction)switchViews:(id)sender {

if (self.yellowViewController.view.superview == nil) { if (self.yellowViewController == nil) {

self.yellowViewController =

[[BIDYellowViewController alloc] initWithNibName:@"YellowView" bundle:nil];

}

[blueViewController.view removeFromSuperview];

[self.view insertSubview:self.yellowViewController.view atIndex:0]; } else {

if (self.blueViewController == nil) { self.blueViewController =

[[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];

}

[yellowViewController.view removeFromSuperview];

[self.view insertSubview:self.blueViewController.view atIndex:0];

}

}

.

.

.

Also, add the following code to the existing didReceiveMemoryWarning method:

-(void)didReceiveMemoryWarning {

//Releases the view if it doesn't have a superview [super didReceiveMemoryWarning];

//Release any cached data, images, etc, that aren't in use if (self.blueViewController.view.superview == nil) {

self.blueViewController = nil;

}else {

self.yellowViewController = nil;

}

}

The first method we modified, viewDidLoad, overrides a UIViewController method that is called when the nib is loaded. How could we tell? Hold down the option key and singleclick the method name viewDidLoad. A documentation popup window will appear (see Figure 6–17). Alternatively, you can select View Utilities Show Quick Help Inspector to view similar information in the Quick Help panel. viewDidLoad is defined in our superclass, UIViewController, and is intended to be overridden by classes that need to be notified when the view has finished loading.

www.it-ebooks.info

154

CHAPTER 6: Multiview Applications

Figure 6–17. This documentation window appears when you option-click the viewDidLoad method name.

This version of viewDidLoad creates an instance of BIDBlueViewController. We use the initWithNibName:bundle: method to load the BIDBlueViewController instance from the nib file BlueView.xib. Note that the file name provided to initWithNibName:bundle: does not include the .xib extension. Once the BIDBlueViewController is created, we assign this new instance to our blueViewController property.

self.blueViewController = [[BIDBlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];

Next, we insert the blue view as a subview of the root view. We insert it at index 0, which tells iOS to put this view behind everything else. Sending the view to the back ensures that the toolbar we created in Interface Builder a moment ago will always be visible on the screen, since we’re inserting the content views behind it.

[self.view insertSubview:self.blueViewController.view atIndex:0];

Now, why didn’t we load the yellow view here also? We’re going to need to load it at some point, so why not do it now? Good question. The answer is that the user may never tap the Switch Views button. The user might just use the view that’s visible when the application launches, and then quit. In that case, why use resources to load the yellow view and its controller?

Instead, we’ll load the yellow view the first time we actually need it. This is called lazy loading, and it’s a standard way of keeping memory overhead down. The actual loading of the yellow view happens in the switchViews: method, so let’s take a look at that.

switchViews: first checks which view is being swapped in by seeing whether yellowViewController’s view’s superview is nil. This will return true if one of two things is true:

If yellowViewController exists but its view is not being shown to the user, that view will not have a superview because it’s not presently in the view hierarchy, and the expression will evaluate to true.

If yellowViewController doesn’t exist because it hasn’t been created yet or was flushed from memory, it will also return true.

www.it-ebooks.info

CHAPTER 6: Multiview Applications

155

We then check to see whether yellowViewController is nil.

if (self.yellowViewController.view.superview == nil) {

If it is nil, that means there is no instance of yellowViewController, and we need to create one. This could happen because it’s the first time the button has been pressed or because the system ran low on memory and it was flushed. In this case, we need to create an instance of BIDYellowViewController as we did for the

BIDBlueViewController in the viewDidLoad method:

if (self.yellowViewController

== nil) {

self.yellowViewController

=

[[BIDYellowViewController

alloc] initWithNibName:@"YellowView"

}

bundle:nil];

 

At this point, we know that we have a yellowViewController instance, because either we already had one or we just created it. We then remove blueViewController’s view from the view hierarchy and add the yellowViewController’s view:

[blueViewController.view removeFromSuperview];

[self.view insertSubview:self.yellowViewController.view atIndex:0];

If self.yellowViewController.view.superview is not nil, then we need to do the same thing, but for blueViewController. Although we create an instance of BIDBlueViewController in viewDidLoad, it is still possible that the instance has been flushed because memory got low. Now, in this application, the chances of memory running out are slim, but we’re still going to be good memory citizens and make sure we have an instance before proceeding:

} else

{

 

if

(self.blueViewController

== nil) {

 

self.blueViewController

=

 

[[BIDBlueViewController

alloc] initWithNibName:@"BlueView"

 

 

bundle:nil];

}

[yellowViewController.view removeFromSuperview];

[self.view insertSubview:self.blueViewController.view atIndex:0];

}

In addition to not using resources for the yellow view and controller if the Switch Views button is never tapped, lazy loading also gives us the ability to release whichever view is not being shown to free up its memory. iOS will call the UIViewController method didReceiveMemoryWarning, which is inherited by every view controller, when memory drops below a system-determined level.

Since we know that either view will be reloaded the next time it is shown to the user, we can safely release either controller. We do this by adding a few lines to the existing didReceiveMemoryWarning method:

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning]; // Releases the view if it

//doesn't have a superview

//Release anything that's not essential, such as cached data if (self.blueViewController.view.superview == nil)

self.blueViewController = nil;

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]