Core Graphics

Bert Carr
3 min readMar 18, 2015

--

Core Graphics (CG), a.k.a. Quartz, is an old C-based API that allows you to draw paths, shapes, shadows and gradients on a graphics destination, or “context”.

The idea behind CG is very simple. If you want to modify any view, you have to subclass it and override its drawRect: method. Since every view has a drawRect: method, you can do this with any UIView subclass. In this way, you can customize buttons, labels, maps and, in general, any graphic object descendant of UIView.

Why should you use CG when you can have a graphic designer create images using Photoshop? You don’t need to use CG code to draw everywhere. In fact, trying to reproduce simple Photoshop effects could be really hard to achieve and would require many lines of code.

However, there are some advantages in using CG instead of pre-loaded graphic objects:

  1. If you need to draw something that changes its visual appearance dynamically.
  2. Reduces the application memory footprint -use CG to draw objects at runtime instead of loading large images from memory.
  3. Reduces the size of the application bundle.
  4. Resolution independence -the same source code can run on the iPhone with or without the retina display, on the iPad with or without the retina display. No need for images in three or four different resolutions.
  5. Scaling pre-loaded images at runtime can have a negative aliasing effect. CG renders objects without this problem.

Three basic concepts to understanding CG: the Graphic Context, the Path and the Graphic State.

Graphic Context

The Graphic Context is your graphic destination. If you want to draw on a view, the view is your Graphic Context. Instead, if you want to draw on an image, the image is your Graphic Context. So, the first thing you should do, before trying to draw anything is to define the Graphic Context. Each Core Graphics function has a pointer to the current graphic context.

You get the current Graphic Context by using the UIGraphicsGetCurrentContext function. So, after subclassing your UIView, you override the drawRect: method and get the current graphic context:

- (void)drawRect:(CGRect)rect 
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
...
}

Now that we have a reference to the current Graphic Context, we could start to draw.

Path

Each drawing is composed of some basic graphic elements: points, lines, arcs. All of them are referred to as Paths. A path is a set of lines, arcs and curves you can draw on the current graphic context to build complex objects. Only when the path description is completed, you can draw the path on the screen and choose to fill it or stroke it or both.

Core Graphics provides you with specific functions to draw paths. Some of these functions are specific and can be used to draw a line, a rectangle, an ellipse, an arc, etc.

CGRect ellipseCenterRect = CGRectInset(nativeRect, 16, 16);CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);CGContextFillEllipseInRect(context, ellipseCenterRect);CGContextAddEllipseInRect(context, ellipseCenterRect);CGContextClip(context);

Graphic State

The Graphic State keeps track of the colors, the size of the path, the transformations and many other features you want to apply to a path or group of paths.

States are maintained in stack. You save the state using CGContextSaveCGState. In this way, you push the graphic state onto the stack. When you want to reload the previous graphic state, you use CGContextRestoreCGState. In this way, the state is popped from the stack.

CGContextSaveGState(context);
{
CGFloat xOffset = highlightOffset.width + round(roundedRectangleBorderRect.size.width);CGFloat yOffset = highlightOffset.height;CGContextSetShadowWithColor(context,CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)),highlightBlurRadius,highlight.CGColor);[roundedRectanglePath addClip];}
CGContextRestoreGState(context);

--

--