How to use the code generated by the PaintCode Plugin for Sketch

The video above provides a detailed step-by-step guide on how to use the generated code. This article provides a summary for more advanced users. The provided code examples are in Swift, but all information below also applies to Objective-C.

Overview

PaintCode plugin for Sketch generates a single class we call "StyleKit". All drawings that you choose to export to code are available as methods in this class.

In your code, you should only use the public interface of this class. This allows you to repeatedly tweak your drawings in Sketch and re-export them at any time. A new StyleKit class will be generated and exported. Because you only use the public API of the class, you won't have to make any manual changes to the generated code to integrate it (or re-integrate it) into your project.

Generated Methods

For each drawing you choose to export (be it page, artboard or slice), two methods will be generated. The first method is a simple void drawing method:

class func drawClock(frame frame: CGRect = CGRect(x: 0, y: 0,
                                                  width: 228, height: 281), 
                        resizing: ResizingBehavior = .AspectFit) {
    ...
}

When executed, this method draws your drawing to the current graphics context. The method takes two parameters. The "frame" parameters specifies the target rectangle into which you want to draw (in points). The "resizing" parameter specifies how the drawing should be fitted into the target frame. In Swift, both parameters are optional. If you omit a parameter, default value will be used instead.

The other method that is generated for your drawing is a method that returns UIImage of your drawing.

class func imageOfClock() -> UIImage {
    ...
}

Using the Generated Methods with UIViews

Perhaps the most typical way to use the generated code is with UIView subclass. Create a UIView subclass and override the drawRect(_ rect: CGRect) method.

In the overriden drawRect method, simply call the drawing method from the generated StyleKit class:

class TestView: UIView {
    override func drawRect(rect: CGRect) {
        StyleKit.drawClock()
    }
}

Typically, you should also specify the "frame" parameter. The usual value to use as the frame is the value of the "bounds" property of the UIView:

class TestView: UIView {
    override func drawRect(rect: CGRect) {
        StyleKit.drawClock(frame: self.bounds)
    }
}

You can also specify the "resizing" parameter to change the way your drawing is fitted into the frame:

class TestView: UIView {
    override func drawRect(rect: CGRect) {
        StyleKit.drawClock(frame: self.bounds, resizing: .AspectFit)
    }
}

The available resizing options are:

Using the Generated Methods with CALayers

You can use also the drawing methods with CALayers. One approach is to use a CALayer subclass and override the drawInContext(_) method:

func drawInContext(_ ctx: CGContext) {
    UIGraphicsPushContext(ctx)
    StyleKit.drawClock()
    UIGraphicsPopContext()
}

Another approach is to use a CALayer delegate's drawLayer(_,inContext:) method:

func drawLayer(_ layer: CALayer, inContext ctx: CGContext) {
    UIGraphicsPushContext(ctx)
    StyleKit.drawClock()
    UIGraphicsPopContext()
}

In both cases, you need to call UIGraphicsPushContext() function before calling the generated code, and then call UIGraphicsPopContext() afterwards. This is because the generated code can only draw to current graphics context. By calling the UIGraphicsPushContext(ctx) function, you make the context that was passed in as a parameter the current context temporarily. Don't forget to call UIGraphicsPopContext() afterwards to properly restore the previous graphics context.

Using the UIImage-generating Methods

On iOS, there are many APIs that expect you to provide UIImage to customize the look of the user interface. For example, you can customize the UITabBarItem by setting its "image" property.

To change the image of UITabBarItem programatically, simply do:

yourTabBarItem.image = StyleKit.imageOfClock()

The imageOfClock method from the generated code will return a UIImage.

Note that if you are creating UITabBarItem in Interface Builder, you shouldn't forget to change its "System Item" attribute to "Custom" - otherwise, you won't be able to customize the image shown by the UITabBarItem.

Generated Constants

By naming your Sketch artboard "Library" and placing shapes on it, you can define colors, gradients and shadows that will be available in the generated code. The name of the shape will be used as the name of the generated color, and the fill color of the shape will be used as the color value. The system works the same way for gradients and shadows (just don't forget to turn the Fill off for shadows).

//MARK: - Colors

static let primaryColor = UIColor(hue: 0.98,
                                  saturation: 0.991,
                                  brightness: 0.816,
                                  alpha: 1)
                                  
static let secondaryColor = UIColor(hue: 0.104,
                                    saturation: 0.856,
                                    brightness: 0.962,
                                    alpha: 1)

//MARK: - Gradients

static let companyGradient = CGGradientCreateWithColors(nil, [
    UIColor(hue: 0.126, saturation: 0.64, brightness: 1, alpha: 1).CGColor, 
    UIColor(hue: 0.072, saturation: 0.997, brightness: 0.999, alpha: 1).CGColor], 
    nil)!

//MARK: - Shadows

static let defaultShadow = NSShadow(color: UIColor(white: 0, alpha: 0.5), 
                                    offset: CGSize(width: 0, height: 2),
                                    blurRadius: 4)

Using these constants in your code is quite straightforward:

yourLabel.textColor = StyleKit.primaryColor

More advanced scenarios

Sometimes, you may need to make your drawing dynamic. For example, you might want to change the color of some part of your drawing depending on the time of day. Or, you may want to implement a very specific resizing behavior. In such cases, you can use the generated code as a starting point for more advanced implementation.

You can either alter the generated code by hand, or you can check out PaintCode, our full-featured vector drawing app that supports variables, expressions, advanced resizing capabilities, parametric symbols and much more. With PaintCode, it is possible to implement many of these advanced scenarios without manually tweaking the generated code.