draw

本文深入探讨了UIKit与CoreGraphics在iOS应用开发中如何实现视图更新、坐标系转换、路径绘制、图像渲染、PDF内容生成及打印支持等关键功能。详细介绍了使用这些技术进行高效、灵活的UI界面与复杂图形内容的创建与呈现,旨在帮助开发者掌握iOS应用中图形与界面设计的核心技巧。

UIKit Function Reference

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 to NO

  • Scrolling a view off of the screen and then back onto the screen

  • Explicitly calling the setNeedsDisplay or setNeedsDisplayInRect: method of your view


  Core Graphics native LLO coordinate system.
 ULO coordinate system of UIKit for drawing operations
Drawing to the Screen
  UIGraphicsGetCurrentContext  

Drawing to Bitmap Contexts and PDF Contexts

UIKit provides functions for rendering images in a bitmap graphics context and for generating PDF content by drawing in a PDF graphics context. Both of these approaches require that you first call a function that creates a graphics context—a bitmap context or a PDF context, respectively. The returned object serves as the current (and implicit) graphics context for subsequent drawing and state-setting calls. When you finish drawing in the context, you call another function to close the context.

Core graphics functions for modifying graphics state

Graphics state

Core Graphics functions

UIKit alternatives

Current transformation matrix (CTM)

CGContextRotateCTM

CGContextScaleCTM

CGContextTranslateCTM

CGContextConcatCTM

None

Clipping area

CGContextClipToRect

UIRectClip function

Line: Width, join, cap, dash, miter limit

CGContextSetLineWidth

CGContextSetLineJoin

CGContextSetLineCap

CGContextSetLineDash

CGContextSetMiterLimit

None

Accuracy of curve estimation

CGContextSetFlatness

None

Anti-aliasing setting

CGContextSetAllowsAntialiasing

None

Color: Fill and stroke settings

CGContextSetRGBFillColor

CGContextSetRGBStrokeColor

UIColor class

Alpha global value (transparency)

CGContextSetAlpha

None

Rendering intent

CGContextSetRenderingIntent

None

Color space: Fill and stroke settings

CGContextSetFillColorSpace

CGContextSetStrokeColorSpace

UIColor class

Text: Font, font size, character spacing, text drawing mode

CGContextSetFont

CGContextSetFontSize

CGContextSetCharacterSpacing

UIFont class

Blend mode

CGContextSetBlendMode

The UIImage class and various drawing functions let you specify which blend mode to use.

Creating and Drawing Paths

UIKit includes the  UIRectFrame  and UIRectFill  functions (among others) for drawing simple paths such as rectangles in your views. 
For more complex paths, you must create the path yourself using the UIBezierPath class of UIKit, or using the functions that operate on the CGPathRef opaque type in the Core Graphics framework

For creating paths in iOS, it is recommended that you use 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);

Hit Detection


A point is not considered to be enclosed by the path if it is inside an open subpath, regardless of whether that area would be painted during a fill operation. Therefore, to determine mouse hits on open paths, you must create a copy of the path object and explicitly close any subpaths (using the  closePath method) before calling this method.


Drawing and Creating Images


 // 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:

  1. 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.



If you prefer using Core Graphics entirely for drawing in a bitmap graphics context, you can use the 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:

  1. Create a PDF context and push it onto the graphics stack (as described in “Creating and Configuring the PDF Context”).

  2. Create a page (as described in “Drawing PDF Pages”).

  3. Use UIKit or Core Graphics routines to draw the content of the page.

  4. Add links if needed (as described in “Creating Links Within Your PDF Content”).

  5. Repeat steps 2, 3, and 4 as needed.

  6. 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.

PDF link的作用不用多说,都是分为两种情况:
   1、调到某一页
         通过两个函数UIGraphicsAddPDFContextD estinationAtPoint和UIGraphicsSetPDFContextD estinationForRect,参数都是一个 能够唯一标识某一目的地的string和点坐标或者一个rect。
UIKit <wbr>Graphics <wbr>System--Creating <wbr>and <wbr>Configuring <wbr>the <wbr>PDF <wbr>Context学习笔记3

   2、跳到某个URL
   通过函数UIGraphicsSetPDFContextU RLForRect,直接为某一个矩形范围内的部分设置对应的链接URL

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.

 These four properties are mutually exclusive; that is, if you assign a value to one of the properties, UIKit makes sure that all the other properties are  nil .

Printing Workflow

The general workflow for printing an image, document, or other printable content of an app is as follows:

  1. Obtain the shared instance of UIPrintInteractionController.

  2. (Optional, but strongly recommended) Create a UIPrintInfo object, set attributes such as output type, job name, and print orientation; then assign the object to the printInfo property of the UIPrintInteractionControllerinstance. (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).

  3. (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.

  4. Assign one of the following to a property of the UIPrintInteractionController instance:

    Only one of these properties can be non-nil for any print job. See “Printing Support Overview” for descriptions of these properties.

  5. If you assigned a page renderer in the previous step, that object is typically an instance of a custom subclass ofUIPrintPageRenderer. 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.)

  6. (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 the addPrintFormatter: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 the printFormatters property of UIPrintPageRenderer.

  7. If the current user-interface idiom is iPad, present the printing interface to the user by callingpresentFromBarButtonItem: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 a printInteractionControllerParentViewController: 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"];

Note: In iOS 4 and later, you may omit the filename extension when specifying image names.

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

Constructing Paths

These functions are used to define the geometry of the current path. For more information on how paths are defined, seeCGPath Reference.

Painting Paths

These functions are used to stroke along or fill in the current path.

Getting Information About Paths

Modifying Clipping Paths

Setting Color, Color Space, and Shadow Values

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

Drawing Text

Converting Between Device Space and User Space



 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值