cocoa drawing

来源:互联网 发布:公司商标起名软件 编辑:程序博客网 时间:2024/04/30 10:03

Drawing is a fundamental part of most Cocoa applications. If your application uses only standard system controls, then Cocoa does all of the drawing for you. If you use custom views or controls, though, then it is up to you to create their appearance using drawing commands.

Cocoa Drawing Support

The Cocoa drawing environment is available to all applications built on top of the Application Kit framework (AppKit.framework). This framework defines numerous classes and functions for drawing everything from primitive shapes to complex images and text. Cocoa drawing also relies on some primitive data types found in the Foundation framework (Foundation.framework).

The Cocoa drawing environment is compatible with all of the other drawing technologies in Mac OS X, including Quartz,OpenGL, Core Image, Core Video, Quartz Composer, PDF Kit, and QuickTime. In fact, most Cocoa classes use Quartz extensively(广阔地) in their implementations to do the actual drawing. In cases where you find Cocoa does not have the features you need, it is no problem to integrate other technologies where necessary to achieve the desired effects.

Because it is based on Quartz, the Application Kit framework provides most of the same features found in Quartz, but in an object-oriented wrapper. Among the features supported directly by the Application Kit are the following:

  • Path-based drawing (also known as vector-based drawing)

  • Image creation, loading and display

  • Text layout and display

  • PDF creation and display

  • Transparency

  • Shadows

  • Color management

  • Transforms

  • Printing support

  • Anti-aliased rendering

  • OpenGL support

Like Quartz, the Cocoa drawing environment takes advantage of graphics hardware wherever possible to accelerate drawing operations. This support is automatic. You do not have to enable it explicitly in your code.

The Drawing Environment

The drawing environment encompasses the digital canvas and graphics settings that determine the final look of your content. The canvas determines where your content is drawn, while the graphics settings control every aspect of drawing, including the size, color, quality, and orientation of your content.

The Graphics Context

You can think of a graphics context as a drawing destination. A graphics context encapsulates all of the information needed to draw to an underlying canvas, including the current drawing attributes and a device-specific representation of the digital paint on the canvas. In Cocoa, graphics contexts are represented by the NSGraphicsContext class and are used to represent the following drawing destinations:

  • Windows (and their views)

  • Images (including bitmaps of all kinds)

  • Printers

  • Files (PDF, EPS)

  • OpenGL surfaces

By far, the most common drawing destination is your application's windows, and by extension its views. Cocoa maintains graphics context objects on a per-window, per-thread basis for your application. This means that for a given window, there are as many graphics contexts for that window as there are threads in your application. Although most drawing occurs on your application's main thread, the additional graphics context objects make it possible to draw from secondary threads as well.

For most other drawing operations, Cocoa creates graphics contexts as needed and configures them before calling your drawing code. In some cases, actions you take may create a graphics context indirectly. For example, when creating a PDF file, you might simply request the PDF data for a certain portion of your view object. Behind the scenes, Cocoa actually creates a graphics context object and calls your view's drawing code to generate the PDF data.

You can also create graphics contexts explicitly to handle drawing in special situations. For example, one way to create a bitmap image is to create the bitmap canvas and then create a graphics context that draws directly to that canvas. There are other ways to create graphics context objects explicitly, although most involve drawing to the screen or to an image. It is very rare that you would ever create a graphics context object for printing or generating PDF or EPS data.

Views and Drawing

Nearly all drawing in Cocoa is done inside views. Views are objects that represent a visual portion of a window. Each view object is responsible for displaying some visual content and responding to user events in its visible area. A view may also be responsible for one or more subviews.

The NSView class is the base class for all view-related objects. Cocoa defines several types of views for displaying standard content, including text views, split views, tab views, ruler views, and so on. Cocoa controls are also based on the NSViewclass and implement interface elements such as buttons, scrollers, tables, and text fields.

In addition to the standard views and controls, you can also create your own custom views. You create custom views in cases where the behavior you are looking for is not provided by any of the standard views. Cocoa notifies your view that it needs to draw itself by sending your view a drawRect: message. Your implementation of the drawRect: method is where all of your drawing code goes.

Note: Although you can also subclass the standard views and controls to implement custom behavior, it is recommended that you try to use a delegate object whenever possible instead. If you do subclass a standard control, avoid changing the appearance of that control. Doing so goes against the guidance in Apple Human Interface Guidelines.

By default, window updates occur only in response to user actions. This means that your view’s drawRect: method is called only when something about your view has changed. For example, Cocoa calls the method when a scrolling action causes a previously hidden part of your view to be exposed. Cocoa also calls it in response to requests from your own code. If the information displayed by your custom view changes, you must tell Cocoa explicitly that you want the appropriate parts of your view updated. You do so by invalidating parts of your view’s visible area. Cocoa collects the invalidated regions together and generates appropriate drawRect: messages to redraw the content.

Although there are numerous ways to draw, a basic drawRect: method has the following structure:

- (void)drawRect:(NSRect)rect
{
    // Draw your content
}

That's it! By the time your drawRect: method is called, Cocoa has already locked the drawing focus on your view, saved the graphics state, adjusted the current transform matrix to your view's origin, and adjusted the clipping rectangle to your view's frame. All you have to do is draw your content.

In reality, your drawRect: method is often much more complicated. Your own method might use several other objects and methods to handle the actual drawing. You also might need to save and restore the graphics state one or more times. Because this single method is used for all of your view's drawing, it also has to handle several different situations. For example, you might want to do more precise drawing during printing or use heavily optimized code during a live resizing operation. The options are numerous and covered in more detail in subsequent chapters.

For additional information about views and live resizing, see View Programming Guide. For more information about printing in Cocoa, see “Customizing a View’s Drawing for Printing” in Printing Programming Topics for Cocoa.

Common Drawing Tasks

Table 1-2 lists some of the common tasks related to drawing the content of your view and offers advice on how to accomplish those tasks.

Table 1-2  Common tasks and solutions

Task

How to accomplish

Draw the content for acustom view.

Implement a drawRect: method in your custom view. Use your implementation of this method to draw content using paths, images, text, or any other tools available to you in Cocoa, Quartz, or OpenGL.

Update a custom view to reflect changed content.

Send a setNeedsDisplayInRect: or setNeedsDisplay: message to the view. Sending either of these messages marks part or all of the view as invalid and in need of an update. Cocoa responds by sending adrawRect: message to your view during the next update cycle.

Animate some content in a view.

Use Core Animation, set up a timer, or use the NSAnimation or NSViewAnimation classes, to generate notifications at a desired frame rate. Upon receiving the timer notification, invalidate part or all of your view to force an update. For information about Core Animation, see Core Animation Programming Guide. For more information about animating with timers, see “Using NSTimer for Animated Content.” For information about using NSAnimation objects, see “Using Cocoa Animation Objects.”

Draw during alive resize.

Use the inLiveResize method of NSView to determine if a live resize is happening. If it is, draw as little as possible while ensuring your view has the look you want. For more information about live resizing optimizations, see Drawing Performance Guidelines.

Draw during aprinting operation.

Use the currentContextDrawingToScreen class method or isDrawingToScreen instance method ofNSGraphicsContext to determine if a print operation is underway. Use the attributes method ofNSGraphicsContext to retrieve (as needed) any additional information about the current print job. Draw images at the best possible resolution. Adjust your graphics in any other ways you think are appropriate to achieve the best possible appearance on the target device. For more information about printing, seePrinting Programming Topics for Cocoa.

CreatePDF orEPS data from a view.

Use the dataWithPDFInsideRect: or dataWithEPSInsideRect: method to obtain the data. In yourdrawRect: method use the currentContextDrawingToScreen class method or isDrawingToScreeninstance method of NSGraphicsContext to determine if a print operation is underway.



原创粉丝点击