129 Practical Drawing for Ios Developers V4 DD F
Total Page:16
File Type:pdf, Size:1020Kb
Practical Drawing for iOS Developers Taking advantage of the Core Graphics API Session 129 Bill Dudney Secret Service Captain or whatever… These are confidential sessions—please refrain from streaming, blogging, or taking pictures 1 What?! I could draw this with Quartz?! 2 3 4 5 6 7 8 9 Agenda 10 11 Gradient Background 12 Gradient Background Clipped 13 Data Grid 14 Clipped Horizontal Grid 15 Clipped Linear Fill 16 Closing Data 17 Volume Data 18 Text Labels 19 Simple Stocks 20 Drawing 21 22 Color Fill @implementation MyView ... - (void)drawRect:(CGRect)rect { ... } ... @end 23 Color Fill @implementation MyView ... - (void)drawRect:(CGRect)rect { [[UIColor redColor] setFill]; UIRectFill(self.bounds); } ... @end 24 Color Fill @implementation MyView ... - (void)drawRect:(CGRect)rect { [[UIColor redColor] setFill]; UIRectFill(self.bounds); } ... @end 25 Gradient Fill - (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); CGGradientRef gradient = [self gradient]; CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), 0.0); CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)); CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0); } 26 Core Graphics Is a C API Quartz 2D Documentation 27 …just now. —Bill Dudney 28 UIKit to the Rescue Much of Core Graphics is covered by UIKit 29 Gradient Fill Get the context - (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); CGGradientRef gradient = [self gradient]; CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), 0.0); CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)); CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0); } 30 Gradient Fill Get the gradient - (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); CGGradientRef gradient = [self gradient]; CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), 0.0); CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)); CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0); } 31 Gradient Fill Create start and end points - (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); CGGradientRef gradient = [self gradient]; CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), 0.0); CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)); CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0); } 32 Gradient Fill Draw the gradient - (void)drawRect:(CGRect)rect { CGContextRef ctx = UIGraphicsGetCurrentContext(); CGGradientRef gradient = [self gradient]; CGPoint startPoint = CGPointMake(CGRectGetMidX(self.bounds), 0.0); CGPoint endPoint = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)); CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0); } 33 Create the Gradient The colors - (CGGradientRef)gradient { if(NULL == _gradient) { CGFloat colors[6] = {138.0f/255.0f, 1.0f, 162.0f/255.0f, 1.0f, 206.0f/255.0f, 1.0f}; CGFloat locations[3] = {0.05f, 0.45f, 0.95f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); _gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); CGColorSpaceRelease(colorSpace); } return _gradient; } 34 Create the Gradient The color stops - (CGGradientRef)gradient { if(NULL == _gradient) { CGFloat colors[6] = {138.0f/255.0f, 1.0f, 162.0f/255.0f, 1.0f, 206.0f/255.0f, 1.0f}; CGFloat locations[3] = {0.05f, 0.45f, 0.95f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); _gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); CGColorSpaceRelease(colorSpace); } return _gradient; } 35 Create the Gradient The color space - (CGGradientRef)gradient { if(NULL == _gradient) { CGFloat colors[6] = {138.0f/255.0f, 1.0f, 162.0f/255.0f, 1.0f, 206.0f/255.0f, 1.0f}; CGFloat locations[3] = {0.05f, 0.45f, 0.95f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); _gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); CGColorSpaceRelease(colorSpace); } return _gradient; } 36 Create the Gradient - (CGGradientRef)gradient { if(NULL == _gradient) { CGFloat colors[6] = {138.0f/255.0f, 1.0f, 162.0f/255.0f, 1.0f, 206.0f/255.0f, 1.0f}; CGFloat locations[3] = {0.05f, 0.45f, 0.95f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); _gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); CGColorSpaceRelease(colorSpace); } return _gradient; } 37 Create the Gradient Cleanup - (CGGradientRef)gradient { if(NULL == _gradient) { CGFloat colors[6] = {138.0f/255.0f, 1.0f, 162.0f/255.0f, 1.0f, 206.0f/255.0f, 1.0f}; CGFloat locations[3] = {0.05f, 0.45f, 0.95f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); _gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 3); CGColorSpaceRelease(colorSpace); } return _gradient; } 38 Basics Understanding the drawing model 39 UIKit Coordinate System (0.0, 0.0) 40 Quartz Is a Geometric System Describe what you want drawn 41 Quartz Is a Geometric System Describe what you want drawn 42 Quartz Is a Geometric System Describe what you want drawn 43 Quartz Is a Geometric System Describe what you want drawn 44 Quartz Is a Geometric System Describe what you want drawn 45 Quartz Is a Geometric System Describe what you want drawn 46 Points Write in points • Points are abstract • No concept of resolution Line Stroke width 2 points • Vector graphics unit is point Length 4 points • A point is on the intersection—just like you learned in geometry 47 Pixels Hardware is pixels • Pixels are concrete • One color per pixel Line Stroke Width 2 points Length 4 points 48 Points and Pixels Core Graphics translates CGContextSetLineWidth(ctx, 2.0); CGContextMoveToPoint(ctx, points[0].x, points[0].y); CGContextLineToPoint(ctx, points[1].x, points[1].y); 49 Thinking in Points • 10-point system font is readable (for many eyes, anyway) • 44x44 point rectangle is a good touch size • 320x480 points for iPhone (3G, 3Gs, and 4) and iPod touch 50 CGContextRef Context properties Path Stroke Color Line Width Fill Color Line Dash Shadow Clip Path Blend Mode Current Transform Matrix 51 CGContextRef Context properties Path Stroke Color 0, 0 Line Width Fill Color Line Dash Shadow Clip Path 400x400 Blend Mode Current Transform Matrix CGContextAddRect(ctx, CGRectMake(0.0, 0.0, 400.0, 400.0)); 52 CGContextRef Context properties Path Stroke Color 0, 0 Line Width Fill Color Line Dash Shadow Clip Path 400x400 Blend Mode Current Transform Matrix CGContextSetFillColorWithColor(ctx, [[UIColor blueColor] CGColor]); 53 CGContextRef Context properties Path Stroke Color 0, 0 Line Width Fill Color Line Dash Shadow Clip Path 400x400 Blend Mode Current Transform Matrix CGContextFillPath(ctx); 54 CGContextRef Context properties Path Stroke Color 0, 0 Line Width Fill Color Line Dash Shadow Clip Path 400x400 Blend Mode Current Transform Matrix [[UIColor blueColor] setFill]; UIRectFill(CGRectMake(0.0, 0.0, 400.0, 400.0)); 55 CGContextRef Context properties • Current transform matrix (CTM) Path Defines “user space” Stroke Color • Line Width • User space is where points live Fill Color Line Dash Shadow Clip Path Blend Mode Current Transform Matrix 56 CGContextRef Context properties Path Stroke Color 0, 0 100, 0 Line Width Fill Color Line Dash Shadow Clip Path 400x400 Blend Mode Current Transform Matrix CGContextTranslateCTM(ctx, 100.0, 0.0); [[UIColor blueColor] setFill]; UIRectFill(CGRectMake(0.0, 0.0, 400.0, 400.0)); 57 CGContextRef Context properties Path • Context stack ■ Stroke Color Save state to take a snapshot ■ Line Width Revert state to return to snapshot Fill Color Line Dash CGContextSaveGState(ctx); Shadow CGContextTranslateCTM(ctx, 100.0, 0.0); // draw in transformed context Clip Path CGContextRestoreGState(ctx); // draw in untransformed context Blend Mode Current Transform Matrix 58 CGContextRef Context properties Path • Context stack ■ Stroke Color Save state to take a snapshot ■ Line Width Revert state to return to snapshot Fill Color Line Dash CGContextSaveGState(ctx); Shadow CGContextTranslateCTM(ctx, 100.0, 0.0); // draw in transformed context Clip Path CGContextRestoreGState(ctx); // draw in untransformed context Blend Mode Current Transform Matrix 59 CGContextRef Context properties Path • Context stack ■ Stroke Color Save state to take a snapshot ■ Line Width Revert state to return to snapshot Fill Color Line Dash CGContextSaveGState(ctx); Shadow CGContextTranslateCTM(ctx, 100.0, 0.0); // draw in transformed context Clip Path CGContextRestoreGState(ctx); // draw in untransformed context Blend Mode Current Transform Matrix 60 CGContextRef Context properties Path • Context stack ■ Stroke Color Save state to take a snapshot ■ Line Width Revert state to return to snapshot Fill Color Line Dash CGContextSaveGState(ctx); Shadow CGContextTranslateCTM(ctx, 100.0, 0.0); // draw in transformed context Clip Path CGContextRestoreGState(ctx); // draw in untransformed context Blend Mode Current Transform Matrix 61 CGContextRef Context properties Path • Context stack ■ Stroke Color Save state to take a snapshot ■ Line Width Revert state to return to snapshot Fill Color Line Dash CGContextSaveGState(ctx); Shadow CGContextTranslateCTM(ctx, 100.0, 0.0); // draw in transformed context Clip Path CGContextRestoreGState(ctx); // draw in untransformed context Blend Mode Current Transform Matrix 62 Don’t Call Us, We’ll Call You No context, no drawing! - (void)tapGestureReceived:(UITapGestureRecognizer