教程一原文:Core Graphics Tutorial Part 1: Getting Started
Behind the scenes in Core Graphics
Each UIView
has a graphics context, and all drawing for the view renders into this context before being transferred to the device’s hardware.
iOS updates the context by calling draw(_:)
whenever the view needs to be updated. This happens when:
- The view is new to the screen.
- Other views on top of it are moved.
- The view’s
hidden
property is changed. - Your app explicitly calls the
setNeedsDisplay()
orsetNeedsDisplayInRect()
methods on the view.
Note: Any drawing done in
draw(_:)
goes into the view’ graphics context. be aware that if you start drawing outside ofdraw(_:)
, as you’ll do in the final part of this tutorial you’ll have to create your own graphics context.
you haven’t used Core Graphics yet in this tutorial because UIKit has wrappers around many of the Core Graphics functions. A UIBezierPath
, for example, is a wrapper for a CGMutablePath
, which is the lower-level Core Graphics API.
Note: Never call
draw(_:)
directly. If your view is not being updated, then callsetNeedsDisplay()
on the view.
setNeedsDisplay()
does not itself calldraw(_:)
, but it flags the view as ‘dirty’, triggering a redraw usingdraw(_:)
on the next screen update cycle. Even if you callsetNeedsDisplay()
five times in the same method you’ll only ever actually calldraw(_:)
once.
Drawing Into the Context
Core Graphics uses a “painter’s model”. When you draw into a context, it’s almost like making a painting. You lay down a path and fill it, and then lay down another path on top and fill it. You can’t change the pixels that have been laid down, but you can “paint” over them.
This image from Apple’s documentation describes how this works. Just as it is when you’re painting on a canvas, the order in which you draw is critical.
Note: Remember that a path simply consists of points. Here’s an easy way to grasp the concept: when creating the path imagine that you have a pen in hand. Put two dots on a page, then place the pen at the starting point, and then draw a line to the next point by drawing a line.
That’s essentially what you do with the above code by using
move(to:)
andaddLine(to:)
.
Points and Pixels
iPad 2:1 point = 1 pixel;
iPhone 6:2x retina screen,1 point = 2 * 2 pixels;
iPhone 6 Plus:3x retina screen,1 point = 3 * 3 pixels。
iOS anti-aliases the half-filled pixels with a color half way between the two colors, and the line looks fuzzy.
If you have oddly sized straight lines, you’ll need to position them at plus or minus 0.5 points to prevent anti-aliasing. If you look at the diagrams above, you’ll see that a half point on the iPad 2 will move the line up half a pixel, on the iPhone 6, up one whole pixel, and on the iPhone 6 Plus, up one and a half pixels.
教程二原文:Core Graphics Tutorial Part 2: Gradients and Contexts
Core Graphics
This image from Apple describes the relevant frameworks conceptually: