PaintCode Review: Dynamic Graphics Made Easy

Bill Morefield
PaintCode - is it worth the money?

PaintCode – is it worth the money?

PaintCode is an app that allows you to draw controls, icons, and other graphics elements like you would in programs like Sketch, Photoshop, or Illustrator.

Except PaintCode has one major difference – it generates Objective-C or Swift Core Graphics code from your drawings in real time!

You can then integrate this code into your app, allowing you to dynamically scale your graphics to any size, or programmatically change your graphics based on user input.

We’ve covered PaintCode in several tutorials in the past (one for developers, one for designers), but if you don’t have PaintCode yet you might be wondering – is it worth the money?

Keep reading to find out! :]

Why PaintCode?

Before we begin, it’s important to understand the problem that PaintCode aims to solve.

As an iOS or OS X developer, you usually receive image assets from designers in terms of PNGs. This works great, but has three major drawbacks:

  1. You need multiple image versions. Since PNGs are made at a specific image size, you need to save multiple versions of each file – such as image.png, image@2x.png, and image@3x.png.
  2. They don’t scale. If you want to scale an image to be larger than the original size, it looks pixelated.
  3. They’re pre-generated. Since the images are pre-generated, you can’t customize them easily at runtime.

This is where PaintCode comes in. By generating the graphics at runtime based on Core Graphics code, your graphics can work on any resolution, scaled as much as you would like – and you can customize the graphics programmatically at run-time.

Let’s take a look at how PaintCode works – starting with a tour!

PaintCode Quick Tour

When you open up PaintCode, you get a blank canvas you can draw into using basic shapes such as rectangles, polygons, ovals, text and Bezier curves. Here’s a happy face icon that I drew in about a minute using an Oval and three stroked Bezier paths:

HappyFace

You can easily give a name to each shape you create in the Canvas pane:

CanvasPane

You can also name the colors that you use in the Colors pane:

ColorsPane

By naming your shapes and colors, the code that PaintCode generates is nice and descriptive. For example, here’s the code that was generated for the happy face:

//// Color Declarations
let faceBackground = NSColor(calibratedRed: 0.956, green: 1, blue: 0.204, alpha: 1)
let faceForeground = NSColor(calibratedRed: 0, green: 0, blue: 0, alpha: 1)
 
//// Face Drawing
let facePath = NSBezierPath(ovalInRect: NSMakeRect(62, 6, 112, 106))
faceBackground.setFill()
facePath.fill()
faceForeground.setStroke()
facePath.lineWidth = 3
facePath.stroke()
 
//// Smile Drawing
var smilePath = NSBezierPath()
smilePath.moveToPoint(NSMakePoint(78.5, 53.5))
smilePath.curveToPoint(NSMakePoint(160.5, 53.5), controlPoint1: NSMakePoint(79.5, 8.15), controlPoint2: NSMakePoint(160.5, 16.39))
NSColor.blackColor().setStroke()
smilePath.lineWidth = 3
smilePath.stroke()
 
//// Right Eye Drawing
var rightEyePath = NSBezierPath()
rightEyePath.moveToPoint(NSMakePoint(102.5, 92.5))
rightEyePath.lineToPoint(NSMakePoint(102.5, 59.5))
NSColor.blackColor().setStroke()
rightEyePath.lineWidth = 3
rightEyePath.stroke()
 
//// Left Eye Drawing
var leftEyePath = NSBezierPath()
leftEyePath.moveToPoint(NSMakePoint(131.5, 92.5))
leftEyePath.lineToPoint(NSMakePoint(131.5, 59.5))
NSColor.blackColor().setStroke()
leftEyePath.lineWidth = 3
leftEyePath.stroke()

How cool is that? Imagine trying to do this on your own via CoreGraphics. It would take ages!

“But wait”, you cry, “I could just design this in Photoshop or Pixelmator, or better yet, Illustrator or Sketch. Why would I switch to PaintCode?!”

Screen Shot 2015-08-24 at 3.47.23 PM

You could, but remember that every time you made a tiny change, like changing the color or size of the happy face, you’d have to re-export your assets. But by generating your code with Core Graphics, you could scale the happy face to any size!

PaintCode and Dynamic Graphics

Although PaintCode’s ability to draw an image at any size at runtime is certainly a benefit, where PaintCode truly shines is its ability to make dynamic graphics.

For example – you could tweak the code above to allow the user to dynamically change the background and foreground color, or even write some code to programmatically generate the size of the happy face’s smile!

DynamicSmile

Let me highlight three features of PaintCode designed to make dynamic graphics easy: the library, variables, and expressions.

The library

PaintCode’s library lets you create, name and manage colors, gradients, and shadows that you can share across all tabs and canvases in your document. Changing the parameter of an item changes it everywhere that item is used.

The library also lets you define colors and gradients based on other items and create colors as highlights, shadows, or transparencies of other colors. Again, changing the base item automatically updates the derived items to match.

The image below shows how changing the base color from red to blue updates the colors derived from the original red:

Derived Colors

Derived Colors

Changing base color to blue changes derived color.

Changing base color to blue changes derived color.

Variables

Variables provide a great deal of flexibility in the generated code; numbers, booleans, points, rectangles, sizes, or colors can all be represented by variables you can attach to a shape’s attributes.

For example, instead of specifying a specific width for a shape, you can create a variable to specify the width when it’s drawn:

DynamicWidth

When you generate code from a drawing, the variables become parameters in the generated methods:

func drawCanvas1(#width: CGFloat) {
    //// Color Declarations
    let faceBackground = UIColor(red: 0.956, green: 1.000, blue: 0.204, alpha: 1.000)
    let faceForeground = UIColor(red: 0.000, green: 0.000, blue: 0.000, alpha: 1.000)
 
    //// Face Drawing
    var facePath = UIBezierPath(ovalInRect: CGRectMake(62, 8, 112, 106))
    faceBackground.setFill()
    facePath.fill()
    faceForeground.setStroke()
    facePath.lineWidth = width
    facePath.stroke()
 
    //// ...
}

Expressions

Expressions are a special type of variable; they perform simple calculations in an easy-to-use language based on a subset of C and Javascript. You can use expressions for things such as setting the color of a shape based on a variable’s value, or calculating the ending angle for a given starting angle of an arc. The expressions then become local variables in the generated code.

While this feature is certainly quite powerful and incredibly useful, I think that using a different language for expressions feels a bit disconnected from the overall paradigm of Mac and iOS development. There’s a lack of autocomplete on the expression syntax; a minor detail, but hopefully one that will be addressed in the future! :]

Example of expression that sets a different color based on a variable.

Example of expression that sets a different color based on a variable.

Using PaintCode for Building Apps

Now that you have a birds-eye view of what PaintCode is and its major features, let’s take a look at how PaintCode can help speed up your application development process.

The raywenderlich.com team tends to use PaintCode for three main things:

  1. Turning drawings into code
  2. Creating icons for applications
  3. Rapid prototyping

Let’s look at each of these in turn.

1) Turning Drawings Into Code

The main use case of PaintCode is turning drawings into code. This is handy for graphics you might want inside your apps, or especially if you are making custom-drawn controls in your app.

As you create and change your elements, PaintCode generates code in real time at the bottom of the document window. Between the canvas and the generated code sits a toolbar where you control how PaintCode generates code to match the target environment for your app.

You can choose either OS X, iOS or the web as the platform target for your code; PaintCode automatically handles the differences between iOS and OS X such as UIColor on iOS as opposed to NSColor on OS X. PaintCode can produce either Objective-C or Swift code for both iOS and OS X.

PaintCode Toolbar

PaintCode Toolbar

One of the great new features in PaintCode 2 is StyleKits. This allows PaintCode to generate a single class containing the drawings in your document and, optionally, items such as colors, gradients, shadows, and images.

To create the StyleKit class, you export your document from PaintCode and select the StyleKit option. You can specify a name for the generated class, along with the project name, author, and company name to be included in the comments of the class, as well as the destination folder where you want to save the generated class.

Exporting StyleKit

Exporting StyleKit

All you have to do is add the StyleKit classes to your application and call the methods and values directly from your code. Below is some sample source code that draws a StyleKit-exported control within a UIView class:

class CountdownView: UIView {
 
    override func drawRect(rect: CGRect) {
        CountdownControl.drawCountdownControl(frame: rect,
          isRunning: false, remaining: 1.0, isWarning: false)
    }
}

This is the result on iOS:

StyleKit code running in simulator

StyleKit Control running in iOS Simulator

The drawing code requires a single method call. How cool is that? Remember – the code most free of bugs is code that you don’t write at all! :]

While PaintCode does generate working code, it does not always produce the most efficient code, nor does it always produce exactly what you need.

“It’s definitely nice to be able to easily draw and tweak custom UI components, and this is usually much faster than doing everything manually in code ‘by hand’. However, I consider PaintCode to be just a starting point.”

–Tutorial team member Joshua Greene

2) Creating Icons for Applications

Retina displays and new devices have certainly complicated things for iOS developers – with @1x, @2x, and @3x along with different devices, now we have image assets galore!

Generating all the icons and graphics for your app to meet requirements for submission to the App Store can take a significant amount of time in PhotoShop or a similar bitmap creation tool.

PaintCode makes this process easy by generating UIImages directly for any drawing use within your app. It can also export your drawings as bitmaps; this gives you a faster path to generating the myriad versions of icons and graphics for your app.

Icon Generation

Generating Retina icons from original drawing.

“[At first I thought PaintCode] was just a program for making overly verbose drawing code, and I wasn’t that impressed with the code output, but I found it really good as a place to do all my vector drawing and icons, and keep my named colors for the app, and to export out all of the images in the various resolutions.

But once I realized I could draw an icon with vectors in one canvas and use that as a symbol for all the millions of other icon sizes and export them all in one go, I was super impressed. To then tweak one of my theme colors and have that reflected instantly in all the drawings was also very good.”

–Tutorial team member Rich Turton

3) Rapid prototyping

It’s important to be able to prototype your graphics changes quickly and easily, and PaintCode has several features to help with that:

  • Reusable symbols. You can’t waste time copying and pasting your updates all through the code when you change elements of your design; instead, PaintCode’s ability to include existing canvases as symbols on other canvases makes it easy to reuse components and propagate your changes.
  • Library items. Similarly, using Library items lets you change colors in your prototype with ease, making it a breeze to try out different UI configurations and themes.
  • Live prototyping (PaintCode 2.4). There’s a cool new feature in PaintCode 2.4 (still in beta at the time of writing) that will allow live prototyping of graphics in apps. You simply run your project with a special framework, and any changes to your PaintCode project will be reflected directly in your prototype app – without even restarting!

“But really I like drawing out controls or possibly interface objects with PaintCode. I think of it like a Photoshop but really I’m curious as to the code behind the control. I’ll throw the code into the app I’m prototyping for an take a screenshot for the designer I’m working with. I find that showing a real interaction with something goes the extra step with design/UX.”

— Tutorial team member Aaron Douglas

Where to Go From Here?

PaintCode is a well designed and powerful app, that does a great job of converting designs to Objective-C and Swift Core Graphics code.

At the time of writing this article, PaintCode is $99.99. Is it worth the money?

Here’s our recommendation:

  • If you need to make dynamic graphics, custom controls with Core Graphics, or want to make resolution-independent graphics for your app: Then yes, PaintCode is a must-have tool in your development arsenal.
  • If you’ve been getting along just fine without Core Graphics: Then although PaintCode is a great tool, you might not need it in your case – hold off until you find a use case for it. PaintCode is a bit of a niche app; it’s great when you need it, but you might not always need it. Remember, plenty of great apps were made without PaintCode :]

And that’s it – happy painting! If you have any questions about PaintCode, or want to share your own experience of using it, please join in the forum discussion below!

Bill Morefield

I'm currently a mobile app and web developer who also has worked in networking and servers. I have been doing iOS development for about two years with my most recent app Coming Light released in November. When not online I can usually be found with a camera in hand or outdoors hiking and quite often both.

Other Items of Interest

Save time.
Learn more with our video courses.

raywenderlich.com Weekly

Sign up to receive the latest tutorials from raywenderlich.com each week, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

PragmaConf 2016 Come check out Alt U

Our Books

Our Team

Video Team

... 20 total!

Swift Team

... 15 total!

iOS Team

... 29 total!

Android Team

... 15 total!

macOS Team

... 10 total!

Apple Game Frameworks Team

... 11 total!

Unity Team

... 11 total!

Articles Team

... 11 total!

Resident Authors Team

... 15 total!