PencilKit: Building a complete drawing app with a few lines of code
In WWDC2019, Apple gifted us with a brand new Apple Pencil framework: the PencilKit. Before that, it was very hard and complex to build a Pencil app only by detecting touching gestures and making Math calculations, but with this new library, it costs only a few lines of code to present a drawing canvas with a simple tool picker.
First, let's start describing the magic around the Pencil Kit by giving a brief introduction of the basic concepts around implementing a drawing app:
The canvas is basically the view where the user can draw something. It corresponds to any surface that sensitive to the Apple Pencil. It can also allow the user to draw with his own fingers. The canvas captures each point touched by the user and renders it within in periodic times(less than one second).
In Swift, The canvas view corresponds to a struct which belongs to the PencilKit framework, which is named PKCanvasView. The PKCanvasView has a delegate object(following the PKCanvasViewDelegate protocol) responsible for answering the drawing events in the canvas. Those events can be:
- canvasViewDidChange: notifies a change in the current drawing
- canvasViewDidFinishRendering: notifies a drawing has finished
- canvasViewDidBeginUsingTool: notifies the user started using a new tool to draw(Ex: switched to a pencil)
- canvasViewDidEndUsingTool: notifies the user finished using a tool
Generally the canvas view controller is assigned to be his delegate, just like the table view delegate and data source, but you can build another object for that.
You can see bellow how to create a canvas view and insert in a view controller:
We are basically setting the constraints to define the canvas dimensions, and setting its background color white, very similar to other UIView components. We must do it inside the viewDidLoad method.
The tool picker, as the name already says, is the component where the user can select a tool to manage the drawing, such as an eraser, a pencil or a pen, defining its configurations. If you have any Apple Pencil app in your iPad, you can see all of them have a tool picker. It corresponds to the PKToolPicker entity.
This type counts with an observer object, which answers to important events involving the tools. Normally, we set the canvas to answer for those events.
Different from other entities, the PKToolPicker is instantiated as a singleton, there is only one tool picker in the entire application, and is obtained from the UIWindow. To be visible on the screen, you must set the canvas as its first responder. Take a look at a setup example of a tool picker:
Notice that, as it must happen very after the canvas instantiation, the tool picker must be created in the viewDidAppear lifecycle method. First, we get the window from the application, then we pick the tool picker from the window through a singleton. After that, we set the picker as visible telling that the canvas is the first responder for its events. We set the canvas as its observer and finally the canvas as the first responder in the parent.
If you want the canvas to set the main tool manually, without using the UI component, you don't need the tool picker after all:
It says that the canvas will set its current tool as an inking tool(a tool used for drawing, which is different from an eraser), with a pen type, the color black and 1 as its width. If you desire, you can use a control UI(as a UISwitch or a UISegmentedControl) to change the tool manually.
Let's now talk about the tools:
PencilKit type that defines a tool for drawing or interacting with the canvas.
- PKInkingTool: Tool for drawing, defining a curve style of the drawing(pen, pencil), a color and the width
- PKEraserTool: Tool that defines an eraser and erases the curves of an inking tool in the canvas. It can define the type of eraser you want to use(whole traces to erase or defined points of touch)
- PKLassoTool: tool which works to cut out specific areas of a canvas
Object that defines the canvas drawing. It can be saved in a UIImage and then saved in the photo library:
You can also reset the canvas to its black state just by resetting the drawing object:
In this article we gave a brief introduction to how the Pencil Kit framework basically works and how you can make a great drawing app with just a few lines of code. I hope you enjoyed! ;)