08 custom drawing & animation · // create basic animation to interpolate position between...
TRANSCRIPT
![Page 2: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/2.jpg)
Frameworks- UIKit - Core Graphics / Quartz - Core Animation - OpenGL ES
![Page 3: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/3.jpg)
UIKit
Core Graphics
OpenGL ESCore
Animation
![Page 4: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/4.jpg)
UIKit
(mostly) Swift/ObjC API UI... classes/functions
![Page 5: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/5.jpg)
Base view class: UIView Pre-built controls: UIControls
UIKit
![Page 6: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/6.jpg)
typically, use concrete subclasses as is (no need to subclass) e.g., UILabel, UIButton, UITableView, UIImageView
UIKit
![Page 7: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/7.jpg)
can also subclass UIView to draw custom UI elements
UIKit
![Page 8: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/8.jpg)
support for - 2D drawing - transformations - predefined transitions - basic animation
UIKit
![Page 9: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/9.jpg)
CG
aka “Quartz 2D” C API for drawing
![Page 10: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/10.jpg)
support for: - layer-based graphics - patterns, gradients, etc. - color spaces - working with bitmaps
CG
![Page 11: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/11.jpg)
mostly, UIKit draws using CG i.e., more than one way of doing anything
CG
![Page 12: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/12.jpg)
CGUIKit
// get current graphics context to draw into CGContextRef context = UIGraphicsGetCurrentContext();
// clear with white rectangle CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); CGContextFillRect(context, self.bounds);
// load image from file CGDataProviderRef provider = CGDataProviderCreateWithFilename(imageFileName); CGImageRef image = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault); CGDataProviderRelease(provider);
// draw image at (0,0) CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); CGImageRelease(image);
// clear with white rectangle UIColor.whiteColor().set() UIRectFill(CGRect(x: 0, y: 0, width: 100, height: 100)) // load and draw image at (0,0) UIImage(named: “image.png")?.drawAtPoint(CGPoint(x: 0, y: 0))
![Page 13: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/13.jpg)
CA
API for animation and compositing
verb [ trans. ] [usu. as n. ] ( compositing) combine (two or more images) to make a single picture, esp. electronically : photographic compositing by computer.
![Page 14: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/14.jpg)
all UIViews are backed by CA layers
CA
![Page 15: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/15.jpg)
can create a hierarchy of CALayers within a single view (in addition to creating a hierarchy of views)
CA
![Page 16: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/16.jpg)
generally, layers are: - more lightweight - more flexible - more complex
CA
![Page 17: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/17.jpg)
CALayer properties can be automatically animated
CA
![Page 18: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/18.jpg)
support for: - simple value interpolation - key frame animation - transition effects - animation groups
CA
![Page 19: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/19.jpg)
CA
// create new CA layer and populate with image CALayer *layer = [CALayer layer]; UIImage *image = [UIImage imageNamed:@"image.png"]; layer.contents = image.CGImage; layer.frame = CGRectMake(0, 0, image.size.width, image.size.height); // add layer to view layer [self.view.layer addSublayer:layer]; // create basic animation to interpolate position between (100,100) and (300,300) CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"]; anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)]; anim.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 300)]; anim.duration = 5.0; anim.autoreverses = YES; anim.repeatCount = HUGE_VALF; anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [layer addAnimation:anim forKey:@"backandforth"];
// load image and add to view at position (100,100) let imageView = UIImageView(image: UIImage(named: "image.png")) imageView.center = CGPoint(x: 100, y: 100) view.addSubview(imageView) // animate using a block -- bounce between start position and (300,300) UIView.animateWithDuration(5.0, delay: 0.0, options: .Repeat | .Autoreverse, animations: { view.center = CGPoint(x: 300, y: 300) }, completion: nil)
UIKit
![Page 20: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/20.jpg)
OpenGL
industry standard 2D/3D graphics API
![Page 21: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/21.jpg)
technically, OpenGL ES; i.e., for Embedded Systems
OpenGL
![Page 22: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/22.jpg)
OpenGL ES 2.0 not backwards compatible (fixed-function vs. shaders)
OpenGL
![Page 23: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/23.jpg)
hardware acceleration iPad 2: CPUx2, GPUx9, iPad 3: CPUx1, GPUx2-3, etc.
OpenGL
![Page 24: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/24.jpg)
OpenGL render destination: CAEAGLLayer in UIView
OpenGL
![Page 25: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/25.jpg)
generally, don’t mix OpenGL and UIKit/CA/CG functions (e.g., no layer transforms)
OpenGL
![Page 26: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/26.jpg)
UIKit
Core Graphics
OpenGL ESCore
Animation
![Page 27: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/27.jpg)
§ Drawing
![Page 28: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/28.jpg)
(0,0)
x
y
320
480
“ULO”
![Page 29: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/29.jpg)
(0,0)x
y
320
480
“ULO”
![Page 30: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/30.jpg)
320 x 480 points (not necessarily = pixels!)
![Page 31: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/31.jpg)
≈ resolution independence scale factor × points = pixels (retina display: scale = 2.0)
![Page 32: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/32.jpg)
principal data types: CGPoint, CGSize, CGRect
/* Points. */ struct CGPoint { var x: CGFloat var y: CGFloat }
/* Sizes. */ struct CGSize { var width: CGFloat var height: CGFloat }
/* Rectangles. */ struct CGRect { var origin: CGPoint var size: CGSize }
![Page 33: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/33.jpg)
/* Return the left/mid/right x-value of ‘rect’. */ CGFloat CGRectGetMinX(CGRect rect); CGFloat CGRectGetMidX(CGRect rect); CGFloat CGRectGetMaxX(CGRect rect);
/* Return the top/mid/bottom y-value of ‘rect’. */ CGFloat CGRectGetMinY(CGRect rect); CGFloat CGRectGetMidY(CGRect rect); CGFloat CGRectGetMaxY(CGRect rect);
/* Return the width/height of ‘rect’. */ CGFloat CGRectGetWidth(CGRect rect); CGFloat CGRectGetHeight(CGRect rect);
/* Standardize ‘rect’ -- i.e., convert it to an equivalent rect which has positive width and height. */ CGRect CGRectStandardize(CGRect rect);
/* Return true if ‘rect’ is empty (that is, if it has zero width or height), false otherwise. A null rect is defined to be empty. */ bool CGRectIsEmpty(CGRect rect);
![Page 34: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/34.jpg)
locating/placing things: frame & bounds rectangles
![Page 35: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/35.jpg)
frame = origin & size in superview’s coordinate system
![Page 36: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/36.jpg)
bounds = origin & size in local view’s coordinate system
![Page 37: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/37.jpg)
application window
![Page 38: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/38.jpg)
application window
view frame: - origin = (6, 5) - size = (15, 10)
view
![Page 39: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/39.jpg)
application window
view
view bounds: - origin = (0, 0) - size = (15, 10)
subview
subview frame: - origin = (3, 4) - size = (6, 5)
![Page 40: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/40.jpg)
size of frame, bounds are automatically linked
![Page 41: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/41.jpg)
reposition view by changing frame origin or center (changing one automatically adjusts the other)
![Page 42: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/42.jpg)
can change bounds origin to adjust local coordinate system
![Page 43: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/43.jpg)
view bounds: - origin = (0, 0) - size = (15, 10)
subview frame: - origin = (3, 4) - size = (6, 5)
![Page 44: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/44.jpg)
view bounds: - origin = (1, 1) - size = (15, 10)
subview frame: - origin = (3, 4) - size = (6, 5)
![Page 45: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/45.jpg)
view bounds: - origin = (-1, 4) - size = (15, 10)
subview frame: - origin = (3, 4) - size = (6, 5)
![Page 46: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/46.jpg)
/* Fill `rect' with solid color */ void UIRectFill(CGRect rect); void UIRectFillUsingBlendMode(CGRect rect, CGBlendMode blendMode);
/* Draw 1px frame inside `rect'. */ void UIRectFrame(CGRect rect); void UIRectFrameUsingBlendMode(CGRect rect, CGBlendMode blendMode);
Simple Drawing
![Page 47: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/47.jpg)
@interface UIColor // Convenience methods for creating autoreleased colors + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
// Some convenience methods to create colors. These colors are cached. + (UIColor *)blackColor; // 0.0 white + (UIColor *)redColor; // 1.0, 0.0, 0.0 RGB + (UIColor *)greenColor; // 0.0, 1.0, 0.0 RGB + (UIColor *)blueColor; // 0.0, 0.0, 1.0 RGB + (UIColor *)clearColor; // 0.0 white, 0.0 alpha
// Set the color: Sets the fill and stroke colors in the current drawing context. - (void)set;
// Set the fill or stroke colors individually. - (void)setFill; - (void)setStroke;
// Access the underlying CGColor @property(nonatomic,readonly) CGColorRef CGColor; @end
Color?
![Page 48: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/48.jpg)
UIKit framework always draws to implicit, current Graphics Context
![Page 49: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/49.jpg)
// establish current drawing context (image buffer) UIGraphicsBeginImageContext(CGSize(width: 100, height: 100))
// clear background with white box UIColor.whiteColor().set() UIRectFill(CGRect(x: 0, y: 0, width: 100, height: 100))
// draw black frame UIColor.blackColor().set() UIRectFrame(CGRect(x: 0, y: 0, width: 100, height: 100))
// draw (filled) blue rectangle UIColor.blueColor().set() UIRectFill(CGRect(x: 10, y: 10, width: 80, height: 80))
// extract image from context let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext()
![Page 50: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/50.jpg)
CG maintains a stack of graphics contexts (empty, by default)
![Page 51: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/51.jpg)
UIView objects automatically push graphics contexts before calling drawRect:
![Page 52: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/52.jpg)
@interface UIView(UIViewRendering) /* All custom drawing must happen from this method. Should limit drawing to ‘rect’ -- on first call ‘rect’ is usually equal to our bounds. */ - (void)drawRect:(CGRect)rect;
/* drawRect: is called lazily. If view must be redrawn, we must notify the system by calling one of these methods below. */ - (void)setNeedsDisplay; - (void)setNeedsDisplayInRect:(CGRect)rect; @end
![Page 53: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/53.jpg)
Q: draw in current view vs. adding subview? - it depends … - subviews allow us to add/remove objects
- but adds memory + processing overhead
![Page 54: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/54.jpg)
demo
HelloWorldViewdiscuss root view frame origin/size
Rectangle1using setNeedsDisplay to force refresh
Rectangle2use multiple views to track drawn rectanglesignore contentStretch for now
GameBoard- handling
![Page 55: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/55.jpg)
subview size > superview?
![Page 56: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/56.jpg)
default: container views don’t clip subviews … but no “scrolling”, either
- to implement, parent may adjust its own bounds to move children into view - or, alternatively, change all child frames
(much messier!)
![Page 57: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/57.jpg)
demo
Clipping Demo- effect of clipsToBounds
ScrollView Demoautomatic pan support based on contentSizealso: pinch to zoom
![Page 58: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/58.jpg)
view transformations: translating, scaling, rotating
![Page 59: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/59.jpg)
common strategy: - draw “unit” object at (0,0) - translate, scale, rotate to
final position/size/orientation
![Page 60: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/60.jpg)
drawRect: can be very lazy i.e., draw once, transform many times
![Page 61: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/61.jpg)
implementation: “affine transform matrices”
![Page 62: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/62.jpg)
=⇥x+ t
x
y + t
y
1⇤
⇥x
0y
0 1⇤=
⇥x y 1
⇤⇥
2
4a b 0c d 0t
x
t
y
1
3
5
transformation matrix
transformed coordinates
original coordinates
x
0 = ax+ cy + t
x
y
0 = bx+ dy + ty
⇥x
0y
0 1⇤=
⇥x y 1
⇤⇥
2
41 0 00 1 0t
x
t
y
1
3
5e.g.
![Page 63: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/63.jpg)
/* The identity transform: [ 1 0 0 1 0 0 ]. */ extern const CGAffineTransform CGAffineTransformIdentity;
/* Return a transform which translates by `(tx, ty)': t' = [ 1 0 0 1 tx ty ] */ CGAffineTransform CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);
/* Return a transform which scales by `(sx, sy)': t' = [ sx 0 0 sy 0 0 ] */ CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
/* Return a transform which rotates by `angle' radians: t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] */ CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)
/* Concatenate translation, scaling, rotation transforms to existing matrices. */ CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty); CGAffineTransform CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy); CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);
struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty; }
![Page 64: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/64.jpg)
for given graphics context (e.g., in drawRect:), change current transform matrix (CTM)
![Page 65: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/65.jpg)
/* Scale the current graphics state's transformation matrix (the CTM) by `(sx, sy)'. */ void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy);
/* Translate the current graphics state's transformation matrix (the CTM) by `(tx, ty)'. */ void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty);
/* Rotate the current graphics state's transformation matrix (the CTM) by `angle' radians. */ void CGContextRotateCTM(CGContextRef c, CGFloat angle);
/* Concatenate the current graphics state's transformation matrix (the CTM) with the affine transform `transform'. */ void CGContextConcatCTM(CGContextRef c, CGAffineTransform transform);
![Page 66: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/66.jpg)
demo
ExpandingFrame
look at RotatingView drawRectmotivate CGContextSave/RestoreGStateexplore frame/bounds relationship
![Page 67: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/67.jpg)
Drawing Other Shapes
cubic & quadratic Bézier curves
![Page 68: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/68.jpg)
@interface UIBezierPath : NSObject<NSCopying, NSCoding> {
+ (UIBezierPath *)bezierPath;
- (void)moveToPoint:(CGPoint)point; - (void)addLineToPoint:(CGPoint)point; - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2; - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint; - (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; - (void)closePath;
+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect; + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect; + (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;
@property(nonatomic) CGPathRef CGPath; @end
![Page 69: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/69.jpg)
Bézier curves can be created, stored, and reused, independent of graphics context
![Page 70: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/70.jpg)
demo
BezierDrawing
![Page 71: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/71.jpg)
rects, curves, etc. = vector graphics ⇒ infinite scaleability
![Page 72: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/72.jpg)
raster graphics? e.g., bitmaps, JPG, PNG
![Page 73: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/73.jpg)
UIKit: load with UIImage
![Page 74: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/74.jpg)
imageNamed:Returns the image object associated with the specified filename.+ (UIImage *)imageNamed:(NSString *)name
Parametersname
The name of the file. If this is the first time the image is being loaded, the method looks for an image with the specified name in the application’s main bundle.
Return ValueThe image object for the specified file, or nil if the method could not find the specified image.
DiscussionThis method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.On a device running iOS 4 or later, the behavior is identical if the device’s screen has a scale of 1.0. If the screen has a scale of 2.0, this method first searches for an image file with the same filename with an @2x suffix appended to it. For example, if the file’s name is button, it first searches for button@2x. If it finds a 2x, it loads that image and sets the scale property of the returned UIImage object to 2.0. Otherwise, it loads the unmodified filename and sets the scale property to 1.0.
![Page 75: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/75.jpg)
caveat emptor: imageNamed cache can be quite aggressive! (Google: “imageNamed cache”)
![Page 76: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/76.jpg)
raster graphics problem: scaling → pixelation
![Page 77: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/77.jpg)
UIView contentStretch property defines which parts of an image are “stretched”
![Page 78: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/78.jpg)
demo
ContentStretching
![Page 79: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/79.jpg)
Image Drawing Options
image = UIImage(named:@"image.png")
let imageView = UIImageView(image: image) view.addSubview(imageView)➊ UIKit (subview)
func drawRect(rect: CGRect) { image.drawAtPoint(CGPoint(x: 0, y: 0)) }
➋ CG (drawing)
let layer = CALayer() layer.contents = image.CGImage view.layer.addSublayer(layer)
➌ CA (compositing)
![Page 80: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/80.jpg)
demo
ImageDrawingrun all three versions (view, layer, drawRect) --- may want to keep num_image < 100 for the lastrun through instruments: memory allocations (num_images=10000 for view, layer version), and time profiler (esp. interesting for drawRect based)
![Page 81: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/81.jpg)
more reading (Xcode library): - View Programming Guide for iOS - Quartz 2D Programming Guide
![Page 82: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/82.jpg)
§ Animation
![Page 83: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/83.jpg)
UIKit / CoreAnimation
![Page 84: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/84.jpg)
typically, use “magic” UIView / CALayer animation mechanism
![Page 85: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/85.jpg)
i.e., provide “new” view properties in animation block along with time frame
— core animation does the rest
![Page 86: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/86.jpg)
note: CA updates happen in a separate thread!
![Page 87: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/87.jpg)
animated parameters are updated according to a specified interpolation curve (aka timing function)
![Page 88: 08 Custom Drawing & Animation · // create basic animation to interpolate position between (100,100) and (300,300) ... @interface UIView(UIViewRendering) /* All custom drawing must](https://reader034.vdocuments.net/reader034/viewer/2022052017/603026c55f29856d1c578015/html5/thumbnails/88.jpg)
timing functions