
This video is only available to subscribers. Start a subscription today to get access to this and 470 other videos.
Gradients
This episode is part of a series: Dive Into Core Graphics.
1. Intro 2 min |
2. Basic Shapes 7 min |
3. Paths 17 min |
4. Colors 9 min |
5. Gradients 11 min |
6. Clipping Paths 6 min |
7. Context Transforms 10 min |
8. Images 7 min |
9. Text 9 min |
10. Offscreen Rendering 12 min |
11. Custom CALayer 13 min |
12. Pie Progress View 7 min |
13. Watermarking Photos 6 min |
14. Working in AppKit 8 min |
Links
Creating a CGGradient
Gradients are created with colorspaces, colors, and locations.
If you specify a color space and any of the colors are in a different color space, then the system will convert them. It is
recommended to just pass colors in a consistent color space to avoid any conversion.
let colors = [
CGColor(colorSpace: colorSpace, components: [0.2, 0.2, 0.8, 1])!,
CGColor(colorSpace: colorSpace, components: [0.6, 0.4, 1, 1])!
] as CFArray
let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: nil)!
Creating a Linear Gradient
A linear gradient will travel along a straight line, filling the perpendicular axis with color defined by the gradient. This is often a vertical line, but doesn't have to be if you want the gradient to travel diagonally.
context.drawLinearGradient(gradient, start: CGPoint(x: 30, y: 30), end: CGPoint(x: 290, y: 290), options: [])
Here the gradient starts at 30, 30
and ends at 290, 290
. By default the gradient won't draw outside the start & end points, so you'll have a clipped drawing. If you want the edges to extend and fill the entire container, then you can specify some options:
context.drawLinearGradient(gradient, start: CGPoint(x: 30, y: 30), end: CGPoint(x: 290, y: 290), options: [
.drawsBeforeStartLocation,
.drawsAfterEndLocation
])
The gradient will just continue repeating the color defined at the start and end of the gradient.
Creating a Radial Gradient
To draw a radial gradient, you'll need at least one point to use as the center:
let center = CGPoint(x: rect.midX, y: rect.midY)
Then we can define a startRadius
which will control how big our "circle" will be. To expand to the edges of our rect:
let startRadius = rect.width / 2
We can ignore the endCenter
and endRadius
for now.
context.drawRadialGradient(gradient, startCenter: center, startRadius: rect.width, endCenter: center, endRadius: 0, options: [])
This will draw a circle with our gradient expanding inward. If we use a non-zero value for endRadius
then we'll end up with a donut, which might be appropriate for some sort of radial control, but often not really useful. Using a different center value will create a sort of tunnel effect.
To have the gradient fill our entire rect, we can either expand the startRadius to rect.width
to ensure that the circle will encompass the entire thing (clipping a significant portion of it) or use the .drawsBeforeStartLocation
option.