CGContext Reference
drawRect:
method.
When a view is first shown or when a portion of the view needs to be redrawn, iOS asks the view to draw its content by calling the view’s drawRect:
method.
There are several actions that can trigger a view update:
-
Moving or removing another view that was partially obscuring your view
-
Making a previously hidden view visible again by setting its
hidden
property toNO
-
Scrolling a view off of the screen and then back onto the screen
-
Explicitly calling the
setNeedsDisplay
orsetNeedsDisplayInRect:
method of your view
Graphics state | Core Graphics functions | UIKit alternatives |
---|---|---|
Current transformation matrix (CTM) | None | |
Clipping area | | |
Line: Width, join, cap, dash, miter limit | None | |
Accuracy of curve estimation | None | |
Anti-aliasing setting | None | |
Color: Fill and stroke settings | | |
Alpha global value (transparency) | None | |
Rendering intent | None | |
Color space: Fill and stroke settings | | |
Text: Font, font size, character spacing, text drawing mode | | |
Blend mode | The |
Creating and Drawing Paths
UIKit includes theUIRectFrame
and
UIRectFill
functions (among others) for drawing simple paths such as rectangles in your views.
UIBezierPath
class of UIKit, or using the functions that operate on the CGPathRef
opaque type in the Core Graphics framework. UIBezierPath
instead of CGPath
functions unless you need some of the capabilities that only Core Graphics provides, such as adding ellipses to paths. CGContextSaveGState(graphicsContext); |
CGContextTranslateCTM(graphicsContext, 0.0, imageHeight); |
CGContextScaleCTM(graphicsContext, 1.0, -1.0); |
CGContextDrawImage(graphicsContext, image, CGRectMake(0, 0, imageWidth, imageHeight)); |
CGContextRestoreGState(graphicsContext); |
UIBezierPath *aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) |
radius:75 |
startAngle:0 |
endAngle:DEGREES_TO_RADIANS(135) |
clockwise:YES]; |
// Create the path data. |
CGMutablePathRef cgPath = CGPathCreateMutable(); |
CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(0, 0, 300, 300)); |
CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(50, 50, 200, 200)); |
|
// Now create the UIBezierPath object. |
UIBezierPath *aPath = [UIBezierPath bezierPath]; |
aPath.CGPath = cgPath; |
aPath.usesEvenOddFillRule = YES; |
|
// After assigning it to the UIBezierPath object, you can release |
// your CGPathRef data type safely. |
CGPathRelease(cgPath); |
// Create an oval shape to draw. |
UIBezierPath *aPath = [UIBezierPath bezierPathWithOvalInRect: |
CGRectMake(0, 0, 200, 100)]; |
|
// Set the render colors. |
[[UIColor blackColor] setStroke]; |
[[UIColor redColor] setFill]; |
|
CGContextRef aRef = UIGraphicsGetCurrentContext(); |
|
// If you have content to draw after the shape, |
// save the current state before changing the transform. |
//CGContextSaveGState(aRef); |
|
// Adjust the view's origin temporarily. The oval is |
// now drawn relative to the new origin point. |
CGContextTranslateCTM(aRef, 50, 50); |
|
// Adjust the drawing options as needed. |
aPath.lineWidth = 5; |
|
// Fill the path before stroking it so that the fill |
// color does not obscure the stroked line. |
[aPath fill]; |
[aPath stroke]; |
|
// Restore the graphics state before drawing any other content. |
//CGContextRestoreGState(aRef); |
closePath
method) before calling this method.
// Draw the image. |
[self.anImage drawAtPoint:CGPointMake(10, 10)]; |
UIImage:
- (void)drawAtPoint:(CGPoint)point; // mode = kCGBlendModeNormal, alpha = 1.0
- (void)drawAtPoint:(CGPoint)point blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
- (void)drawInRect:(CGRect)rect; // mode = kCGBlendModeNormal, alpha = 1.0
- (void)drawInRect:(CGRect)rect blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha;
the CGContextDrawImage
function to draw bitmap images
Creating New Images Using Bitmap Graphics Contexts
In UIKit, the procedure is as follows:
-
Call
UIGraphicsBeginImageContextWithOptions
to create a bitmap context and push it onto the graphics stack.
For the first parameter (size
), pass a CGSize
value to specify the dimensions of the bitmap context (in points).
For the second parameter (opaque
), if your image contains transparency (an alpha channel), pass NO
. Otherwise, pass YES
to maximize performance.
For the final parameter (scale
), pass 0.0
for a bitmap that is scaled appropriately for the main screen of the device, or pass the scale factor of your choice.
UIGraphicsBeginImageContextWithOptions(CGSizeMake(100.0,100.0), NO, 2.0);
2.Use UIKit or Core Graphics routines to draw the content of the image into the newly created graphics context.
3.Call the UIGraphicsGetImageFromCurrentImageContext
function to generate and return a UIImage
object based on what you drew. If desired, you can continue drawing and call this method again to generate additional images.
4.Call UIGraphicsEndImageContext
to pop the context from the graphics stack.
CGBitmapContextCreate
function to create the context and draw your image contents into it. When you finish drawing, call the
CGBitmapContextCreateImage
function to obtain a
CGImageRef
object from the bitmap context. You can draw the Core Graphics image directly or use this it to initialize a
UIImage
object. When finished, call the
CGContextRelease
function on the graphics context.
UIGraphicsBeginImageContextWithOptions(CGSizeMake(320,100),NO,1.0);
[view_.layerrenderInContext:UIGraphicsGetCurrentContext()];
UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil);
CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); |
pdfScale = self.frame.size.width/pageRect.size.width; |
pageRect.size = CGSizeMake(pageRect.size.width * pdfScale, pageRect.size.height * pdfScale); |
UIGraphicsBeginImageContextWithOptions(pageRect.size, YES, pdfScale); |
CGContextRef context = UIGraphicsGetCurrentContext(); |
|
// First fill the background with white. |
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); |
CGContextFillRect(context,pageRect); |
CGContextSaveGState(context); |
|
// Flip the context so that the PDF page is rendered right side up |
CGContextTranslateCTM(context, 0.0, pageRect.size.height); |
CGContextScaleCTM(context, 1.0, -1.0); |
|
// Scale the context so that the PDF page is rendered at the |
// correct size for the zoom level. |
CGContextScaleCTM(context, pdfScale,pdfScale); |
CGContextDrawPDFPage(context, page); |
CGContextRestoreGState(context); |
UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext(); |
UIGraphicsEndImageContext(); |
backgroundImageView = [[UIImageView alloc] initWithImage:backgroundImage]; |
Generating PDF Content
It consists of the following steps:
-
Create a PDF context and push it onto the graphics stack (as described in “Creating and Configuring the PDF Context”).
-
Create a page (as described in “Drawing PDF Pages”).
-
Use UIKit or Core Graphics routines to draw the content of the page.
-
Add links if needed (as described in “Creating Links Within Your PDF Content”).
-
Repeat steps 2, 3, and 4 as needed.
-
End the PDF context (as described in “Creating and Configuring the PDF Context”) to pop the context from the graphics stack and, depending on how the context was created, either write the resulting data to the specified PDF file or store it into the specified
NSMutableData
object.
UIGraphicsBeginPDFContextToData
UIGraphicsBeginPDFContextToFile
UIGraphicsEndPDFContext
UIGraphicsBeginPDFPage
UIGraphicsBeginPDFPageWithInfo
UIGraphicsGetPDFContextBounds
UIGraphicsAddPDFContextDestinationAtPoint
UIGraphicsSetPDFContextDestinationForRect
UIGraphicsSetPDFContextURLForRect

The UIKit Printing
More importantly, the print interaction controller lets your app provide the content to be printed. TheUIPrintInteractionController
class provides three distinct ways to print content:
-
Static images or PDFs. For simple content, you can use the print interaction controller’s
printingItem
orprintingItems
properties to provide an image (in various formats), a PDF file, or an array of images and PDF files. -
Print formatters. If you need to print text and HTML content with automatic reflow, you can assign an instance of any of the built-in print formatter classes to the print interaction controller’s
printFormatter
property. -
Page renderers. Page renderers let you provide your own drawing routines for custom content, and give you complete control over the page layout, including headers and footers. To use a page renderer, you must first write a page renderer subclass, then assign an instance of it to the print interaction controller’s
printPageRenderer
property.
nil
.
Printing Workflow
The general workflow for printing an image, document, or other printable content of an app is as follows:
-
Obtain the shared instance of
UIPrintInteractionController
. -
(Optional, but strongly recommended) Create a
UIPrintInfo
object, set attributes such as output type, job name, and print orientation; then assign the object to theprintInfo
property of theUIPrintInteractionController
instance. (Setting the output type and job name are strongly recommended.)If you don’t assign a print-info object, UIKit assumes default attributes for the print job (for example, the job name is the app name).
-
(Optional) Assign a custom controller object to the
delegate
property. This object must adopt theUIPrintInteractionControllerDelegate
protocol. The delegate can do a range of tasks. It can respond appropriately when printing options are presented and dismissed, and when the print job starts and ends. It can return a parent view controller for the print interaction controller.Also, by default, UIKit chooses a default paper size and printable area based on the output type, which indicates the kind of content your app is printing. If your app needs more control over paper size, you can override this standard behavior. See “Specifying Paper Size, Orientation, and Duplexing Options” for more details.
-
Assign one of the following to a property of the
UIPrintInteractionController
instance:-
A single
NSData
,NSURL
,UIImage
, orALAsset
object containing or referencing PDF data or image data to theprintingItem
property. -
An array of directly printable images or PDF documents to the
printingItems
property. Array elements must beNSData
,NSURL
,UIImage
, orALAsset
objects containing, referencing, or representing PDF data or images in supported formats. -
A
UIPrintFormatter
object to theprintFormatter
property. Print formatters perform custom layout of printable content. -
A
UIPrintPageRenderer
object to theprintPageRenderer
property.
Only one of these properties can be non-
nil
for any print job. See “Printing Support Overview” for descriptions of these properties. -
-
If you assigned a page renderer in the previous step, that object is typically an instance of a custom subclass of
UIPrintPageRenderer
. This object draws pages of content for printing when requested by the UIKit framework. It can also draw content in headers and footers of printed pages. A custom page renderer must override one or more of the “draw” methods and, if it is drawing at least part of the content (excluding headers and footers), it must compute and return the number of pages for the print job. (Note that you can use an instance ofUIPrintPageRenderer
“as-is” to connect a series of print formatters.) -
(Optional) If you are using a page renderer, you can create one or more
UIPrintFormatter
objects using concrete subclasses of this class; then add the print formatters for specific pages (or page ranges) to theUIPrintPageRenderer
instance either by calling theaddPrintFormatter:startingAtPageAtIndex:
method ofUIPrintPageRenderer
or by creating an array of one or more print formatters (each with its own starting page) and assigning that array to theprintFormatters
property ofUIPrintPageRenderer
. -
If the current user-interface idiom is iPad, present the printing interface to the user by calling
presentFromBarButtonItem:animated:completionHandler:
orpresentFromRect:inView:animated:completionHandler:
; if the idiom is iPhone or iPod touch, callpresentAnimated:completionHandler:
. Alternatively, you can embed the printing UI into your existing UI by implementing aprintInteractionControllerParentViewController:
delegate method. If your app uses an activity sheet (in iOS 6.0 and later), you can also add a printing activity item.
UIPrintInteractionController *controller;
controller = [UIPrintInteractionController sharedPrintController];
if(controller) {
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if(!completed && error){
#ifdef DEBUG
NSLog(@"FAILED! due to error in domain %@ with error code %u",
error.domain, error.code);
#endif
}
};
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = name;
printInfo.duplex = UIPrintInfoDuplexLongEdge;
controller.printInfo = printInfo;
controller.showsPageRange = YES;
UIViewPrintFormatter *viewFormatter = [webView viewPrintFormatter];
viewFormatter.startPage = 0;
controller.printFormatter = viewFormatter;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CGRect rect;
rect = button.frame;
[controller presentFromRect:rect inView:button.superview animated:YES completionHandler:completionHandler];
} else {
[controller presentAnimated:YES completionHandler:completionHandler];
}
}
Loading Images into Your App
if you have two image files, named Button.png
and Button@2x.png
, you would use the following code to request your button image:
UIImage *anImage = [UIImage imageNamed:@"Button"]; |
On devices with high-resolution screens, the imageNamed:
, imageWithContentsOfFile:
, andinitWithContentsOfFile:
methods automatically looks for a version of the requested image with the @2x
modifier in its name. If it finds one, it loads that image instead. If you do not provide a high-resolution version of a given image, the image object still loads a standard-resolution image (if one exists) and scales it during drawing.
Managing Graphics Contexts
Saving and Restoring the Current Graphics State
Getting and Setting Graphics State Parameters
CGContextGetInterpolationQuality
CGContextSetFlatness
CGContextSetInterpolationQuality
CGContextSetLineCap
CGContextSetLineDash
CGContextSetLineJoin
CGContextSetLineWidth
CGContextSetMiterLimit
CGContextSetPatternPhase
CGContextSetFillPattern
CGContextSetRenderingIntent
CGContextSetShouldAntialias
CGContextSetStrokePattern
CGContextSetBlendMode
CGContextSetAllowsAntialiasing
CGContextSetAllowsFontSmoothing
CGContextSetShouldSmoothFonts
CGContextSetAllowsFontSubpixelPositioning
CGContextSetShouldSubpixelPositionFonts
CGContextSetAllowsFontSubpixelQuantization
CGContextSetShouldSubpixelQuantizeFonts
Constructing Paths
These functions are used to define the geometry of the current path. For more information on how paths are defined, seeCGPath Reference.
CGContextAddArc
CGContextAddArcToPoint
CGContextAddCurveToPoint
CGContextAddLines
CGContextAddLineToPoint
CGContextAddPath
CGContextCopyPath
CGContextAddQuadCurveToPoint
CGContextAddRect
CGContextAddRects
CGContextBeginPath
CGContextClosePath
CGContextMoveToPoint
CGContextAddEllipseInRect
Painting Paths
These functions are used to stroke along or fill in the current path.
CGContextClearRect
CGContextDrawPath
CGContextEOFillPath
CGContextFillPath
CGContextFillRect
CGContextFillRects
CGContextFillEllipseInRect
CGContextStrokePath
CGContextStrokeRect
CGContextStrokeRectWithWidth
CGContextReplacePathWithStrokedPath
CGContextStrokeEllipseInRect
CGContextStrokeLineSegments
Getting Information About Paths
CGContextIsPathEmpty
CGContextGetPathCurrentPoint
CGContextGetPathBoundingBox
CGContextPathContainsPoint
Modifying Clipping Paths
CGContextClip
CGContextEOClip
CGContextClipToRect
CGContextClipToRects
CGContextGetClipBoundingBox
CGContextClipToMask
Setting Color, Color Space, and Shadow Values
CGContextSetAlpha
CGContextSetCMYKFillColor
CGContextSetFillColor
CGContextSetCMYKStrokeColor
CGContextSetFillColorSpace
CGContextSetFillColorWithColor
CGContextSetGrayFillColor
CGContextSetGrayStrokeColor
CGContextSetRGBFillColor
CGContextSetRGBStrokeColor
CGContextSetShadow
CGContextSetShadowWithColor
CGContextSetStrokeColor
CGContextSetStrokeColorSpace
CGContextSetStrokeColorWithColor
Transforming User Space
These functions allow you to examine and change the current transformation matrix (CTM) in a graphics context.
Using Transparency Layers
Drawing an Image to a Graphics Context
Drawing PDF Content to a Graphics Context
Drawing With a Gradient
Drawing With a Shading
Setting Up a Page-Based Graphics Context
Drawing Glyphs
CGContextShowGlyphs
CGContextShowGlyphsAtPoint
CGContextShowGlyphsWithAdvances
CGContextShowGlyphsAtPositions
Drawing Text
CGContextGetTextMatrix
CGContextGetTextPosition
CGContextSelectFont
CGContextSetCharacterSpacing
CGContextSetFont
CGContextSetFontSize
CGContextSetTextDrawingMode
CGContextSetTextMatrix
CGContextSetTextPosition
CGContextShowText
CGContextShowTextAtPoint
Converting Between Device Space and User Space
CGContextGetUserSpaceToDeviceSpaceTransform
CGContextConvertPointToDeviceSpace
CGContextConvertPointToUserSpace
CGContextConvertSizeToDeviceSpace
CGContextConvertSizeToUserSpace
CGContextConvertRectToDeviceSpace
CGContextConvertRectToUserSpace