Since we’re going to do our drawing in a subclass of UIView, let’s set up that class with everything it needs except for the actual code to do the drawing, which we’ll add later.
Single-click QuartzFunView.h, and make the following changes:
#import <UIKit/UIKit.h>
#import "Constants.h"
@interface QuartzFunView : UIView { CGPoint firstTouch;
CGPoint lastTouch;
UIColor *currentColor;
ShapeType shapeType;
UIImage *drawImage;
BOOL useRandomColor;
}
@property CGPoint firstTouch;
@property CGPoint lastTouch;
@property (nonatomic, retain) UIColor *currentColor;
@property ShapeType shapeType;
@property (nonatomic, retain) UIImage *drawImage;
@property BOOL useRandomColor;
@end
The first thing we do is import the Constants.h header we just created so we can make use of our enumerations.
We then declare our instance variables. The first two will track the user’s finger as it drags across the screen. We’ll store the location where the user first touches the screen in firstTouch. We’ll store the location of the user’s finger while dragging and when the drag ends in lastTouch. Our drawing code will use these two variables to determine where to draw the requested shape.
Next, we define a color to hold the user’s color selec- tion and a ShapeType to keep track of the shape the user wants drawn. After that is a UIImage property that will hold the image to be drawn on the screen when the user selects the rightmost toolbar item on the bottom toolbar (see Figure 12-6). The last property is a Boolean that will be used to keep track of whether the user is requesting a random color.
Switch to QuartzFunView.m, and make the following changes:
Figure 12-6. When drawing a UIImage to the screen, notice that the color control disappears.
24594ch12.indd 408 6/25/09 6:06:12 PM
Download at Boykma.Com
CHAPTER 12: Drawing with Quartz and OpenGL 409
#import "QuartzFunView.h"
#import "UIColor-Random.h"
@implementation QuartzFunView
@synthesize firstTouch;
@synthesize lastTouch;
@synthesize currentColor;
@synthesize shapeType;
@synthesize drawImage;
@synthesize useRandomColor;
- (id)initWithCoder:(NSCoder*)coder {
if ( ( self = [super initWithCoder:coder] ) ) { self.currentColor = [UIColor redColor];
self.useRandomColor = NO;
if (drawImage == nil)
self.drawImage = [UIImage imageNamed:@"iphone.png"];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) { // Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code }
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if (useRandomColor)
self.currentColor = [UIColor randomColor];
UITouch *touch = [touches anyObject];
firstTouch = [touch locationInView:self];
lastTouch = [touch locationInView:self];
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:self];
[self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:self];
24594ch12.indd 409 6/25/09 6:06:13 PM
Download at Boykma.Com
CHAPTER 12: Drawing with Quartz and OpenGL
410
[self setNeedsDisplay];
}
- (void)dealloc {
[currentColor release];
[drawImage release];
[super dealloc];
}
@end
Because this view is getting loaded from a nib, we first implement initWithCoder:. Keep in mind that object instances in nibs are stored as archived objects, which is the exact same mechanism we used in the previous chapter to archive and load our objects to disk. As a result, when an object instance is loaded from a nib, neither init: nor initWithFrame:
ever gets called. Instead, initWithCoder: is used, so this is where we need to add any initialization code. In our case, we set the initial color value to red, initialize useRan- domColor to NO and load the image file that we’re going to draw. You don’t have to fully understand the rest of the code here. We’ll get into the details of working with touches and the specifics of the touchesBegan:withEvent:, touchesMoved:withEvent:, and
touchesEnded:withEvent: methods in Chapter 13. In a nutshell, these three methods inherited from UIView (but actually declared in UIView’s parent UIResponder) can be over- ridden to find out where the user is touching the iPhone’s screen.
touchesBegan:withEvent: gets called when the user’s finger first touch the screen. In that method, we change the color if the user has selected a random color using the new
randomColor method we added to UIColor earlier. After that, we store the current loca- tion so that we know where the user first touched the screen, and we indicate that our view needs to be redrawn by calling setNeedsDisplay on self.
The next method, touchesMoved:withEvent:, gets continuously called while the user is dragging a finger on the screen. All we do here is store off the new location in lastTouch
and indicate that the screen needs to be redrawn.
The last one, touchesEnded:withEvent:, gets called when the user lifts that finger off of the screen. Just like in the touchesMoved:withEvent: method, all we do is store off the final location in the lastTouch variable and indicate that the view needs to be redrawn.
Don’t worry if you don’t fully grok what the three methods that start with touches are doing;
we’ll be working on these in much greater detail in the next few chapters.
We’ll come back to this class once we have our application skeleton up and running. That
drawRect: method, which is currently empty except for a comment, is where we will do this
24594ch12.indd 410 6/25/09 6:06:13 PM
Download at Boykma.Com
CHAPTER 12: Drawing with Quartz and OpenGL 411
application’s real work, and we haven’t written that yet. Let’s finish setting up the application before we add our drawing code.