Quartz has a number of advanced capabilities that go beyond simple line drawings. In this section, we’ll look at using gradients, images, and words.
Drawing gradients
Gradients are a core part of SDK design, because they’re a clearly evident aspect of the standard user interface. Unfortunately, there’s no UIKit-level class for creating gradients; instead, you have to fall back on Quartz.
转载:http://blog.youkuaiyun.com/a21064346/article/details/8470332
(网上找到的一篇外文)
You can create gradients in Quartz in two ways: using a CGShadingRef object or a CGGradientRef object. As is often the case in Core Foundation functions, the difference is in complexity. CGGradientRef allows you to draw simple gradients, and CGShadingRef requires you to define a CGFunctionRef object to precisely calculate how the colors in the gradient are displayed. As you’ve probably guessed, we’ll talk about CGGradientRef here and point you to the Apple class references for CGShadingRef.
Table 13.11 CGColorSpace, CGGradient, and CGContext functions for drawing gradients
Function | Arguments | Summary |
CGColorSpaceCreateWithName | color space constant | Creates a color space by name |
CGGradientCreateWithColors | color space, color array, location array | Creates a gradient using pregenerated colors |
CGGradientCreateWithColorComponents | color space, color components array, location array, color count | Creates a gradient with an array of color parts |
CGContextDrawLinearGradient | context, gradient, start CGPoint, end CGPoint, options | Draws a linear gradient |
CGContextDrawRadialGradient | context, gradient, start center, start radius, end center, end radius, options | Draws a radial gradient |
CGColorSpaceRelease | color space | Frees up a color space object |
CGGradientRelease | gradient | Frees up a gradient object |
Drawing a gradient is a four-step process:
1 Define the color space, which you usually do by calling CGColorSpaceCreate-DeviceRGB for the iPhone and iPad.
2 Define the gradient by listing colors and where they appear in the gradient, from 0 to 1. You can do this two ways. You can hand off an array of CGColors (which may be useful if you want to generate them using UIColors), or you can hand off a longer array that defines the colors using another method, such as RGBA.
3 Draw the gradient as a linear gradient (going from point to point) or a radial gradient (going from the center to the edge of a circle).
4 Free up the memory.
The following code shows the steps required to draw a three-color linear gradient that spans an entire iPhone screen:
This code steps through the steps we just listed, defining the color space, creating the parts of the gradient, drawing it, and cleaning up after it. As usual, you can find more info about gradients in the CGGradient reference. For now, though, we’re ready to move on to the next advanced category of Quartz work: images.
Drawing images
In topic 11, you saw one way to work with images, using methods that largely hid the specifics of graphical contexts from you as a programmer. Now that you’re fully immersed in Quartz, you can choose to use the Core Graphics functions instead.
THE IMAGE FUNCTIONS
The two major Core Graphics functions for drawing are listed in table 13.12.
Table 13.12 Two image functions in Quartz
Function | Arguments | Summary |
CGContextDrawImage | context, CGRect, image | Draws an image scaled to fit the rectangle |
CGContextDrawTiledImage | context, CGRect, image | Draws an image scaled to fit the rectangle but filling the current clip region |
These functions both require a CGImageRef, but remember that you can use the CGImage property of a UIImage to produce one. Alternatively, you can use the commands described in the CGImage reference, which offer more precise functionality, to create a new CGImage. Our suggestion is to go with what you know, which means using the UIKit methods, unless they can’t do what you need.
There’s one big gotcha to using the Quartz-related image-drawing functions: they produce a flipped image because they use Quartz’s native coordinate system internally. We’ll show you how to fix that momentarily.
DRAWING ON A BITMAP
Often, you’ll want to turn an image into a bitmap and modify it before displaying it on the screen, most frequently so that you can make multiple uses of the image. We’ll offer a quick example of crossing out a picture here.
Part of what’s unique about this example is that you can do all your drawing work without ever showing the image to the user (unlike if you were drawing on a UIView), thus opening up the possibility of many image-editing functions. When you do decide to display your newly saved image, you’ll see results like the image in figure 13.4.
Figure 13.4 You can change a UIImage without showing it to the user.
The code needed to accomplish this simple crossing out is shown in the next listing.
Listing 13.1 Using bitmaps to edit images
The process of modifying an image involves relatively few steps. You start by creating your bitmap context. Next, you apply any transformations that you want to use for the picture O. If you want to rotate or scale the original picture, here’s where you do it. Likewise, you can use a combination of translations and the context size to easily crop an image. In this example, you flip the picture over by applying a rotation and a translation, to account for the fact that CGContextDrawImage produces an inverted picture. (You’ll see an alternative way to do this in the next example.)
When your transformations are finished, you can draw your image and then draw whatever you want on top of it C (or modify it in some other way). Finally, you save the new picture.
We’ll return to the idea of drawing on pictures in section 13.6 (though we’ll do it in a much more interactive way), but in the meantime we’re ready to draw words.
Drawing words
Unlike Canvas, Quartz supports drawing words on top of your pictures. The functions required are intricate, though, and we generally suggest using UILabel or other UIKit objects and placing them on top of your Quartz objects. But if you need words in Quartz (either because you’re interweaving the words with other Quartz content or because you’re adding words to a picture), you’ll need to use the CGContext text options.
The majority of the text-related functions modify the graphical state, as described in table 13.13. The last two functions in the table draw your text.
You can find several other text-related functions in the CGContext reference. Most notably, if you need more control over your fonts (and particularly if you want to link up to UIFonts), you should use CGContextSetFont and CGContextSetFontSize instead of the CGContextSelectFont function that’s noted here—but keep in mind that you can’t use CGContextShowTextAtPoint when you set your font in this alternative way.
Table 13.13 A variety of functions for drawing text in Quartz
Function | Arguments | Summary |
CGContextSelectFont | context, font name, size, text encoding | Sets a font for the graphical state |
CGContextSetTextDrawingMode | context, CGTextDrawingMode | Defines how to draw text in the graphical state |
CGContextSetTextMatrix | context, affine transform | Places a transformation matrix in the graphical state for drawing only text |
CGContextSetSetPosition | context, x, y | Sets where to draw in the graphical state |
CGContextShowText | context, string, length | Draws the text at the current position |
CGContextShowTextAtPoint | context, x, y, string, length | Draws the text at the specified position |
Here’s a simple example of printing text in Quartz:
The only thing of note is the creation of the affine transformation matrix, flip. We’ve already pointed out that the text-drawing functions don’t use the iOS coordinate system at present. Instead, they’re stored in an inverted manner, so you need to flip them over to use them correctly. (We hope that this changes in some future release of iOS.)
The affine transformation shown here describes the matrix using the CGAffine-TransformMake function. It effectively does the same thing as the two-part transformation in listing 13.1. In our view, it’s a bit simpler but less clear.
That’s only the basics of using text, but it should be enough to get you started when you need to draw in Quartz.
What we didn’t cover
Quartz 2D is a fully featured drawing and painting language that we can only briefly touch on in this topic. Among the other topics you may want to research if you’re going to do more advanced work with Quartz are patterns, transparency layers, layer drawing, and PDF creation. As we’ve mentioned previously, Apple’s "Quartz 2D Programming Guide" is an excellent introduction to these topics.
We’re not quite finished with Quartz. Before we finish this topic, we’ll put together an example that combines some of the Quartz lessons from this topic with some of the photographic work we covered in topic 11.