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
hiddenproperty toNO -
Scrolling a view off of the screen and then back onto the screen
-
Explicitly calling the
setNeedsDisplayorsetNeedsDisplayInRect: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
UIGraphicsBeginImageContextWithOptionsto 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
NSMutableDataobject.
UIGraphicsBeginPDFContextToDataUIGraphicsBeginPDFContextToFileUIGraphicsEndPDFContextUIGraphicsBeginPDFPageUIGraphicsBeginPDFPageWithInfoUIGraphicsGetPDFContextBoundsUIGraphicsAddPDFContextDestinationAtPointUIGraphicsSetPDFContextDestinationForRectUIGraphicsSetPDFContextURLForRect
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
printingItemorprintingItemsproperties 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
printFormatterproperty. -
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
printPageRendererproperty.
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
UIPrintInfoobject, set attributes such as output type, job name, and print orientation; then assign the object to theprintInfoproperty of theUIPrintInteractionControllerinstance. (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
delegateproperty. This object must adopt theUIPrintInteractionControllerDelegateprotocol. 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
UIPrintInteractionControllerinstance:-
A single
NSData,NSURL,UIImage, orALAssetobject containing or referencing PDF data or image data to theprintingItemproperty. -
An array of directly printable images or PDF documents to the
printingItemsproperty. Array elements must beNSData,NSURL,UIImage, orALAssetobjects containing, referencing, or representing PDF data or images in supported formats. -
A
UIPrintFormatterobject to theprintFormatterproperty. Print formatters perform custom layout of printable content. -
A
UIPrintPageRendererobject to theprintPageRendererproperty.
Only one of these properties can be non-
nilfor 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
UIPrintFormatterobjects using concrete subclasses of this class; then add the print formatters for specific pages (or page ranges) to theUIPrintPageRendererinstance either by calling theaddPrintFormatter:startingAtPageAtIndex:method ofUIPrintPageRendereror by creating an array of one or more print formatters (each with its own starting page) and assigning that array to theprintFormattersproperty 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
CGContextGetInterpolationQualityCGContextSetFlatnessCGContextSetInterpolationQualityCGContextSetLineCapCGContextSetLineDashCGContextSetLineJoinCGContextSetLineWidthCGContextSetMiterLimitCGContextSetPatternPhaseCGContextSetFillPatternCGContextSetRenderingIntentCGContextSetShouldAntialiasCGContextSetStrokePatternCGContextSetBlendModeCGContextSetAllowsAntialiasingCGContextSetAllowsFontSmoothingCGContextSetShouldSmoothFontsCGContextSetAllowsFontSubpixelPositioningCGContextSetShouldSubpixelPositionFontsCGContextSetAllowsFontSubpixelQuantizationCGContextSetShouldSubpixelQuantizeFonts
Constructing Paths
These functions are used to define the geometry of the current path. For more information on how paths are defined, seeCGPath Reference.
CGContextAddArcCGContextAddArcToPointCGContextAddCurveToPointCGContextAddLinesCGContextAddLineToPointCGContextAddPathCGContextCopyPathCGContextAddQuadCurveToPointCGContextAddRectCGContextAddRectsCGContextBeginPathCGContextClosePathCGContextMoveToPointCGContextAddEllipseInRect
Painting Paths
These functions are used to stroke along or fill in the current path.
CGContextClearRectCGContextDrawPathCGContextEOFillPathCGContextFillPathCGContextFillRectCGContextFillRectsCGContextFillEllipseInRectCGContextStrokePathCGContextStrokeRectCGContextStrokeRectWithWidthCGContextReplacePathWithStrokedPathCGContextStrokeEllipseInRectCGContextStrokeLineSegments
Getting Information About Paths
CGContextIsPathEmptyCGContextGetPathCurrentPointCGContextGetPathBoundingBoxCGContextPathContainsPoint
Modifying Clipping Paths
CGContextClipCGContextEOClipCGContextClipToRectCGContextClipToRectsCGContextGetClipBoundingBoxCGContextClipToMask
Setting Color, Color Space, and Shadow Values
CGContextSetAlphaCGContextSetCMYKFillColorCGContextSetFillColorCGContextSetCMYKStrokeColorCGContextSetFillColorSpaceCGContextSetFillColorWithColorCGContextSetGrayFillColorCGContextSetGrayStrokeColorCGContextSetRGBFillColorCGContextSetRGBStrokeColorCGContextSetShadowCGContextSetShadowWithColorCGContextSetStrokeColorCGContextSetStrokeColorSpaceCGContextSetStrokeColorWithColor
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
CGContextShowGlyphsCGContextShowGlyphsAtPointCGContextShowGlyphsWithAdvancesCGContextShowGlyphsAtPositions
Drawing Text
CGContextGetTextMatrixCGContextGetTextPositionCGContextSelectFontCGContextSetCharacterSpacingCGContextSetFontCGContextSetFontSizeCGContextSetTextDrawingModeCGContextSetTextMatrixCGContextSetTextPositionCGContextShowTextCGContextShowTextAtPoint
Converting Between Device Space and User Space
CGContextGetUserSpaceToDeviceSpaceTransformCGContextConvertPointToDeviceSpaceCGContextConvertPointToUserSpaceCGContextConvertSizeToDeviceSpaceCGContextConvertSizeToUserSpaceCGContextConvertRectToDeviceSpaceCGContextConvertRectToUserSpace
本文深入探讨了UIKit与CoreGraphics在iOS应用开发中如何实现视图更新、坐标系转换、路径绘制、图像渲染、PDF内容生成及打印支持等关键功能。详细介绍了使用这些技术进行高效、灵活的UI界面与复杂图形内容的创建与呈现,旨在帮助开发者掌握iOS应用中图形与界面设计的核心技巧。
2822

被折叠的 条评论
为什么被折叠?



