Thursday, June 18, 2009

Drawing in a UIView on the iPhone

Stanford University has a class for iPhone development online that you can follow here. I got stuck on assignment 3, because you are asked to draw polygons in a UIView, but they give no information on how to do drawing. The Apple documentation is pretty dense, but I was able to figure it out after a bit of trial and error.

Update: I discovered that the Stanford lecture 5 does cover drawing, out of order from assignment 3, but this may still be useful as a bare bones introduction to drawing.

The API you will use for drawing is the Core Graphics framework, or Quartz 2D API, and is in C, not Objective-C. Because of this, in some cases you might need to do some conversions between C data types and Objective-C objects.

Most of the drawing functions operate upon the CGContext data type, and take a reference to the CGContext as the first argument. The context contains the state of the view that you are going to draw, such as the coordinates of the points to be drawn, background colors and such.
To get this reference, simply call UIGraphicsGetCurrentContext(). This is from the UIKit framework and is a C function. The UIKit framework is the iPhone counterpart to the Cocoa AppKit.

When your iPhone app is run, a message is sent to the drawRect: method, which you must implement in your UIView subclass. This is where your drawing code will go. One thing that initially confused me about this is that drawRect: implies drawing a rectangle, but it refers to the entire view, not the contents within it. I was expecting to find methods such as drawCircle, drawPolygon, etc. But as I said above, the actual drawing is not done in Objective-C, it is done by the Core Graphics framework, and drawRect: is a place to contain those operations.

The following code snippet draws a triangle.


- (void)drawRect:(CGRect)rect
{
// Start by getting your context, you will need it
// for the rest of the drawing functions.
CGContextRef context = UIGraphicsGetCurrentContext();

// This array holds all of the points to be put into the context.
CGPoint points[3];
points[0] = CGPointMake (10.0, 10.0);
points[1] = CGPointMake (100.0, 10.0);
points[2] = CGPointMake (10.0, 100.0);

// Set background color of the context to white.
// Arguments 2, 3, and 4 represent red, green, and blue, respectively.
// The last argument is the opacity.
// The value ranges are between 0.0 and 1.0.
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.0);

// Paint the base of the context.
CGContextFillRect(context, rect);

// Set color of the lines to black, with full opacity.
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);

// Add the coordinates of the lines to the context.
// The last argument is the number of elements in the array.
CGContextAddLines(context, points, 3);

// Connect the end of the last line to the first
// to close the triangle.
CGContextClosePath(context);

// Finally draw your lines.
CGContextStrokePath(context);
}


When you run this, you should see a right triangle in the upper left corner of the view.

If you see that any of this information is inaccurate, let me know and I'll correct it.

1 comment: