Graphics iPhone




CS185c

Chris Pollett

Nov. 10, 2010

Outline

Graphics on the iPhone

Getting Context in Quartz

Drawing into a Context

The Coordinate System

Specifying Color

Drawing Images in a Context

Drawing Shapes: Polygons, Lines and Curves

Demo App

UIColor-Random

Constants.h

QuartzTestView.h

QuartzTestView.m

Here is the implementation of QuartzTestView. The drawRect method is where we override the base UIView ways of drawing things. We also have code to handle touch events (when they start, end and how they change).


#import "QuartzTestView.h"
#import "UIColor-Random.h"


@implementation QuartzTestView

@synthesize firstTouch;
@synthesize lastTouch;
@synthesize currentColor;
@synthesize shapeType;
@synthesize drawImage;
@synthesize useRandomColor;

//we're using initWithCoder as we are loading the view from a nib
// and so init and initWithFrame will never be called
-(id)initWithCoder:(NSCoder *)coder
{
    if((self = [super initWithCoder:coder])) {
        self.currentColor = [UIColor redColor];
        self.useRandomColor = NO;
    if(drawImage == nil)
        self.drawImage = [UIImage imageNamed:@"myphoto.png"];
    }
    return self;
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect 
{
    CGContextRef context = UIGraphicsGetCurrentContext();
	
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, currentColor.CGColor);
    CGContextSetFillColorWithColor(context, currentColor.CGColor);

    CGRect currentRect = CGRectMake(
        (firstTouch.x > lastTouch.x) ? lastTouch.x : firstTouch.x,
        (firstTouch.y > lastTouch.y) ? lastTouch.y : lastTouch.y,
        fabsf(firstTouch.x - lastTouch.x), 
        fabsf(firstTouch.y -lastTouch.y));
    switch (shapeType)
    {
        case kLineShape:
           CGContextMoveToPoint(context, firstTouch.x, firstTouch.y);
           CGContextAddLineToPoint(context, lastTouch.x, lastTouch.y);
           CGContextStrokePath(context);
        break;

        case kRectShape:
           CGContextAddRect(context, currentRect);
           CGContextDrawPath(context, kCGPathFillStroke);
        break;

        case kEllipseShape:
           CGContextAddEllipseInRect(context, currentRect);
           CGContextDrawPath(context, kCGPathFillStroke);
        break;

        case kImageShape: {
           CGFloat horizontalOffset = drawImage.size.width/2;
			
           CGFloat verticalOffset = drawImage.size.width/2;
           CGPoint drawPoint = CGPointMake(lastTouch.x - horizontalOffset, 
               lastTouch.y - verticalOffset);
           [drawImage drawAtPoint:drawPoint];
        break;
        }
        default:
        break;
    }
}

// Basic idea for touch handlers is to store in fields the touch info and redraw
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    if(useRandomColor)
        self.currentColor = [UIColor randomColor];
    UITouch *touch = [touches anyObject]; //touches recieves all 
                                          //finger presses we just need one
    firstTouch = [touch locationInView:self]; //store touch start info
    lastTouch = [touch locationInView:self];

    [self setNeedsDisplay]; // redraw view
}
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"hi there, this method does nothing");
}
	
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{	
    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:self];
    [self setNeedsDisplay]; // redraw view	
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:self];
    [self setNeedsDisplay]; // redraw view	
}

- (void)dealloc 
{
    [currentColor release];
    [drawImage release];
    [super dealloc];
}

@end

QuartzTestViewController.h

QuartzTestViewController.m

QuartzTestViewController.xib