The Painter’s Model
iOS uses a painter’s model to draw in contexts. Unless you specify otherwise, all new drawing is added on top of the existing drawing. This is similar to the way a painter physically applies pigments to a canvas. You modify a context by overlaying new drawing operations.
Listing 1-8 demonstrates this model. Its code builds two circular Bezier paths. It draws the left one in purple, then the right one in green. Figure 1-6 shows the result. The green circle overlaps and obscures part of the original purple drawing.
Figure 1-6 The green circle is drawn after the purple one, covering up part of that original drawing.
Listing 1-8 Drawing Overlapping Circles
- (UIImage *) buildImage { // Create two circular shapes CGRect rect = CGRectMake(0, 0, 200, 200); UIBezierPath *shape1 = [UIBezierPath bezierPathWithOvalInRect:rect]; rect.origin.x += 100; UIBezierPath *shape2 = [UIBezierPath bezierPathWithOvalInRect:rect]; UIGraphicsBeginImageContext(CGSizeMake(300, 200)); // First draw purple [purpleColor set]; [shape1 fill]; // Then draw green [greenColor set]; [shape2 fill]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
If you reverse this drawing order, drawing shape2 first and then shape1, you get the results shown in Figure 1-7. Although the positions and colors are identical to those in Figure 1-6, the purple shape is drawn second. It obscures part of the green circle. The most recently drawn pigments are added to the canvas on top of the existing content.
Figure 1-7 Reversing the drawing order causes the purple circle to obscure part of the green circle.
Translucency
When drawing, translucency plays an important role when painting. Adjusting the purple color’s alpha component changes the result of the drawing operation. Here, the color’s translucency is set to half its normal value:
purpleColor = [purpleColor colorWithAlphaComponent:0.5f];
Figure 1-8 shows the result of drawing the purple circle with the adjusted alpha level. Although the purple color still covers the green shape, its translucency allows you to see through it to the green color, which was laid down first.
Figure 1-8 Using a partially translucent purple color enables you to see the green shape “behind” the purple drawing.
Although, as you’re about to discover, the “rules” of drawing can change programmatically, one thing stays constant: The new source material you draw into a context always affects whatever context is already there, regardless of the mathematics applied. This applies even when using blend modes, such as “destination atop,” where the source material is only drawn into clear areas that are not already filled by context data.
The key lies in understanding that there’s a source that you’re adding, whether it’s a shape, a line, or an image, and a destination you’re drawing to, which is represented by the context. The additive nature of drawing routines enables you to lay down one drawing element at a time, to iteratively build up to the goal you’re working toward, just as a painter draws on a real-world canvas.