CS185c
Chris Pollett
Nov. 10, 2010
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); CGContextMoveToPoint(context, 100.0f, 100.0f); CGContextAddLineToPoint(context, 200.0f, 200.0f); CGContextStrokePath(context);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
[UIColor colorWithRed:1.0f green: 0.0f blue: 0.0f alpha:1.0f];
CGPoint drawPoint = CGPointMake(100.0f, 100.0f); [image drawAtPoint: drawPoint];
CGRect theRect = CGRectMake(0, 0, 100, 100); CGContextAddEllipseInRect(context, theRect); CGContextDrawPath(context, kCGPathFillStroke);
#import <UIKit/UIKit.h> @interface UIColor(Random) +(UIColor *)randomColor; @end
#import "UIColor-Random.h" @implementation UIColor(Random) +(UIColor *)randomColor { static BOOL seeded = NO; if(!seeded) { seeded = YES; srandom(time(NULL)); } CGFloat red = (CGFloat)random()/(CGFloat)RAND_MAX; CGFloat blue = (CGFloat)random()/(CGFloat)RAND_MAX; CGFloat green = (CGFloat)random()/(CGFloat)RAND_MAX; return [UIColor colorWithRed: red green:green blue:blue alpha:1.0f]; } @end
typedef enum { kLineShape = 0, kRectShape, kEllipseShape, kImageShape } ShapeType; typedef enum { kRedColorTab = 0, kBlueColorTab, kYellowColorTab, kGreenColorTab, kRandomColorTab } ColorTabIndex; #define degreesToRadians(x) (3.1415926535897932846 * x /180)
#import <UIKit/UIKit.h> #import "Constants.h" @interface QuartzTestView : 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
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
#import <UIKit/UIKit.h> @interface QuartzTestViewController : UIViewController { IBOutlet UISegmentedControl *colorControl; } @property (nonatomic, retain) UISegmentedControl *colorControl; -(IBAction)changeColor:(id)sender; -(IBAction)changeShape:(id)sender; @end
#import "QuartzTestViewController.h" #import "QuartzTestView.h" #import "UIColor-Random.h" #import "Constants.h"; @implementation QuartzTestViewController @synthesize colorControl; - (IBAction)changeColor:(id)sender { UISegmentedControl *control = sender; NSInteger index = [control selectedSegmentIndex]; QuartzTestView *quartzView = (QuartzTestView *)self.view; switch (index) { case kRedColorTab: quartzView.currentColor = [UIColor redColor]; quartzView.useRandomColor = NO; break; case kBlueColorTab: quartzView.currentColor = [UIColor blueColor]; 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; [(QuartzTestView *)self.view setShapeType:[control selectedSegmentIndex]]; if([control selectedSegmentIndex] == kImageShape) colorControl.hidden = YES; else colorControl.hidden = NO; } - (void)viewDidLoad { [super viewDidLoad]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; } - (void)dealloc { [colorControl release]; [super dealloc]; } @end