If you refer to Figure 12-1, you’ll see that our interface includes two segmented controllers, one at the top and one at the bottom of the screen. The one on top, which lets the user select color, is applicable to only three of the four options on the bottom, so we’re going to need an outlet to that top segmented controller, so we can hide it when it doesn’t serve a purpose. We also need two methods, one that will be called when a new color is selected and another that will be called when a new shape is selected.
Single-click QuartzFunViewController.h, and make the following changes:
#import <UIKit/UIKit.h>
@interface QuartzFunViewController : UIViewController { UISegmentedControl *colorControl;
}
@property (nonatomic, retain) IBOutlet UISegmentedControl *colorControl;
- (IBAction)changeColor:(id)sender;
- (IBAction)changeShape:(id)sender;
@end
Nothing there should need explanation at this point, so switch over to QuartzFunView Controller.m, and make these changes to the top of the file:
#import "QuartzFunViewController.h"
#import "QuartzFunView.h"
#import "Constants.h"
@implementation QuartzFunViewController
@synthesize colorControl;
- (IBAction)changeColor:(id)sender { UISegmentedControl *control = sender;
NSInteger index = [control selectedSegmentIndex];
QuartzFunView *quartzView = (QuartzFunView *)self.view;
switch (index) { case kRedColorTab:
quartzView.currentColor = [UIColor redColor];
quartzView.useRandomColor = NO;
break;
case kBlueColorTab:
quartzView.currentColor = [UIColor blueColor];
24594ch12.indd 411 6/25/09 6:06:13 PM
Download at Boykma.Com
CHAPTER 12: Drawing with Quartz and OpenGL
412
quartzView.useRandomColor = NO;
break;
case kYellowColorTab:
quartzView.currentColor = [UIColor yellowColor];
quartzView.useRandomColor = NO;
break;
case kGreenColorTab:
quartzView.currentColor = [UIColor greenColor];
quartzView.useRandomColor = NO;
break;
case kRandomColorTab:
quartzView.useRandomColor = YES;
break;
default:
break;
} }
- (IBAction)changeShape:(id)sender { UISegmentedControl *control = sender;
[(QuartzFunView *)self.view setShapeType:[control selectedSegmentIndex]];
if ([control selectedSegmentIndex] == kImageShape) colorControl.hidden = YES;
else
colorControl.hidden = NO;
} ...
Let’s also be good memory citizens by adding the following code to the existing
viewDidUnload and dealloc methods:
...
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.colorControl = nil;
[super viewDidUnload];
}
- (void)dealloc {
[colorControl release];
[super dealloc];
} ...
Again, these code changes are pretty straightforward. In the changeColor: method, we look at which segment was selected and create a new color based on that selection. We cast
24594ch12.indd 412 6/25/09 6:06:13 PM
Download at Boykma.Com
CHAPTER 12: Drawing with Quartz and OpenGL 413
view to QuartzFunView. Next, we set its currentColor property so that it knows what color to use when drawing, except when a random color is selected, in which case, we just set the view’s useRandomColor property to YES. Since all the drawing code will be in the view itself, we don’t have to do anything else in this method.
In the changeShape: method, we do something similar. However, since we don’t need to create an object, we can just set the view’s shapeType property to the segment index from
sender. Recall the ShapeTypeenum? The four elements of the enum correspond to the four toolbar segments at the bottom of the application view. We set the shape to be the same as the currently selected segment, and we hide and unhide the colorControl based on whether the Image segment was selected.
Updating QuartzFunViewController.xib
Before we can start drawing, we need to add the segmented controls to our nib and then hook up the actions and outlets. Double-click QuartzFunViewController.xib to open the file in Interface Builder. The first order of business is to change the class of the view, so single-click the View icon in the window labeled QuartzFunViewController.xib, and press ⌘4 to open the identity inspector. Change the class from UIView to QuartzFunView.
Next, look for a Navigation Bar in the library. Make sure you are grabbing a Navigation Bar—
not a Navigation Controller. We just want the bar that goes at the top of the view. Place the Navigation Bar snugly against the top of the view window, just beneath the status bar.
Next, look for a Segmented Control in the library, and drag that right on top of the Navigation Bar. Drop it in the center of the nav bar, not on the left or right side. Once you drop it, it should stay selected, so grab one of the resize dots on either side of the segmented control and resize it so that it takes up the entire width of the navigation bar. You won’t get any blue guide lines, but Interface Builder won’t let you make the bar any bigger than you want it in this case, so just drag until it won’t expand any further.
With the segmented control still selected, press ⌘1 to bring up the attributes inspector, and change the number of segments from 2 to 5. Double-click each segment in turn, changing its label to (from left to right) Red, Blue, Yellow, Green, and Random in that order. At this point, your View window should look
like Figure 12-7. Figure 12-7. The completed
navigation bar
24594ch12.indd 413 6/25/09 6:06:13 PM
Download at Boykma.Com
CHAPTER 12: Drawing with Quartz and OpenGL
414
Control-drag from the File’s Owner icon to the segmented control, and select the colorCon- trol outlet. Make sure you are dragging to the segmented control and not the nav bar. Next, make sure the segmented control is selected, and press ⌘2 to bring up the connections inspector. Drag from the Value Changed event to File’s Owner, and select the changeColor:
action.
Now look for a Toolbar in the library, and drag one of those over to the bottom of the win- dow. The Toolbar from the library has a button on it that we don’t need, so select it and press the delete button on your keyboard. Once it’s placed and the button is deleted, grab another Segmented Control, and drop it onto the toolbar.
As it turns out, segmented controls are a bit harder to center in a toolbar, so we’ll bring in a little help. Drag a Flexible Space Bar Button Item from the library onto the toolbar, to the left of our segmented control. Next, drag a second Flexible Space Bar Button Item onto the toolbar, to the right of our segmented control. These items will keep the segmented control centered in the toolbar as we resize it. Click the segmented control to select it, and resize it so it fills the toolbar with just a bit of space to the left and right. Interface Builder won’t give you guides or stop you from making it wider than the toolbar the way it did with the naviga- tion bar, so you’ll have to be a little careful to resize it to the right size.
Next, with the segmented control still selected, press ⌘1 to bring up the attributes inspec- tor, and change the number of segments from 2 to 4. Change the titles of the four segments to be Line, Rect, Ellipse, and Image, in that order. Switch to the connections inspector, and connect Value Changed event to File’s Owner’s changeShape: action method. Save and close the nib, and go back to Xcode.
Note
You may have wondered why we put a navigation bar at the top of the view and a toolbar at the bottom of the view. According to the iPhone Human Interface Guidelines published by Apple, navigation bars were specifically designed to be placed at the top of the screen and toolbars are designed for the bottom. If you read the descriptions of the Toolbar and Navigation Bar in Interface Builder’s library window, you’ll see this design intention spelled out.
Make sure that everything is in order by compiling and running. You won’t be able to draw shapes on the screen yet, but the segmented controls should work, and when you tap the Image segment in the bottom control, the color controls should disappear. Once you’ve got everything working, let’s do some drawing.
24594ch12.indd 414 6/25/09 6:06:13 PM
Download at Boykma.Com
CHAPTER 12: Drawing with Quartz and OpenGL 415