pencilkit
Add Apple Pencil drawing with PKCanvasView, PKToolPicker, PKDrawing serialization/export, stroke inspection, and PencilKit/PaperKit handoffs. Use when building drawing apps, annotation features, handwriting capture, signature fields, content-version-safe ink workflows, or Apple Pencil-powered experi
By dpearson2699 · 2,656 installs
npx skills add dpearson2699/swift-ios-skills --skill pencilkit
Source repository · Upstream listing
PencilKit
Capture Apple Pencil and finger input using PKCanvasView , manage drawing
tools with PKToolPicker , serialize drawings with PKDrawing , and wrap PencilKit in SwiftUI.
Contents
[Setup]( setup)
[Capture to Export Workflow]( capture to export workflow)
[PKCanvasView Basics]( pkcanvasview basics)
[PKToolPicker]( pktoolpicker)
[PKDrawing Serialization]( pkdrawing serialization)
[Content Version Compatibility]( content version compatibility)
[Exporting to Image]( exporting to image)
[Stroke Inspection]( stroke inspection)
[SwiftUI Integration]( swiftui integration)
[PaperKit Relationship]( paperkit relationship)
[Common Mistakes]( common mistakes)
[Review Checklist]( review checklist)
[References]( references)
Setup
PencilKit requires no entitlements or Info.plist entries. Import PencilKit
and create a PKCanvasView .
Platform availability: iOS 13+, iPadOS 13+, Mac Catalyst 13.1+, visionOS 1.0+.
Capture to Export Workflow
1. Capture: Read canvasView.drawing from
canvasViewDrawingDidChange( :) ; keep the previous persisted revision until
the new revision completes the remaining checkpoints.
2. Serialize: Create dataRepresentation() , write atomically, and run the
[decode validate/fix/retry loop]( decode validatefixretry loop). Do not mark
bytes valid when PKDrawing(data:) still throws.
3. Version gate: Apply [Content Version Compatibility]( content version compatibility)
before editable sync. If the recipient cannot load the drawing, preserve the
full fidelity source and use an existing compatible fallback or read only
preview.
4. Sync: Send only validated, compatible data and mark the revision synced
after acknowledgement. On transport or conflict failure, retain the pending
revision, resolve the cause, and retry without discarding the last good copy.
5. Export: Validate a nonempty drawing region and intended scale before
calling image(from:scale:) ; skip export on invalid bounds without altering
the serialized drawing.
PKCanvasView Basics
PKCanvasView is a UIScrollView subclass that captures Apple Pencil and
finger input and renders strokes.
Drawing Policies
Policy Behavior
.default Respects UIPencilInteraction.prefersPencilOnlyDrawing when the tool picker is visible; otherwise Pencil only
.anyInput Both pencil and finger draw
.pencilOnly Only Apple Pencil touches draw on the canvas
Use .default for system standard Pencil primary canvases when the tool
picker's drawing policy control should follow the user's Pencil preference. Use
.anyInput for signature pads, whiteboards, or explicit finger drawing modes.
Use .pencilOnly when finger input should never create strokes.
Configuring the Canvas
PKToolPicker
PKToolPicker displays a floating palette of drawing tools. The canvas
automatically adopts the selected tool.
Custom Tool Picker Items
Create a tool picker with specific tools. PKToolPicker(toolItems:) and
custom tool picker item classes require iOS/iPadOS 18+, Mac Catalyst 18+, and
visionOS 2+; those item classes are available on macOS starting in macOS 26.
Ink Types
Type Description
.pen Smooth, pressure sensitive pen
.pencil Textured pencil with tilt shading
.marker Semi transparent highlighter
.monoline Uniform width pen
.fountainPen Variable width calligraphy pen
.watercolor Blendable watercolor brush
.crayon Textured crayon
.reed Reed pen (iOS/iPadOS/macOS/visionOS 26+)
Content Versions
Use [Content Version Compatibility]( content version compatibility) as the
single version map and compatibility gate for both the canvas and tool picker.
PKDrawing Serialization
PKDrawing is a value type (struct) that holds all stroke data. Serialize
it to Data for persistence.
Decode Validate/Fix/Retry Loop
For synced or user provided data: validate with PKDrawing(data:) ; on
failure preserve the original bytes and fix the cause by refetching an
intact revision or selecting a previously generated compatible copy; then
retry the decode. Assign the drawing only after a successful retry. If
recovery still fails, keep the source unchanged and show an error or available
read only preview instead of suppressing the failure with try? .
Combining Drawings
Transforming Drawings
Content Version Compatibility
For sync, migration, downgrade, or cross device editing tasks, use
requiredContentVersion as the compatibility gate and choose an explicit
maximumSupportedContentVersion when old clients must keep editing.
If a drawing requires a newer version than a recipient can load, preserve the
full fidelity PKDrawing for capable clients and provide a read only preview or
separate fallback instead of silently overwriting it. See
[references/pencilkit patterns.md](references/pencilkit patterns.md) for the
deeper compatibility table.
Exporting to Image
Generate a UIImage from a drawing.
Stroke Inspection
Access individual strokes, their ink, and control points.
Constructing Strokes Programmatically
Load [Constructing Strokes Programmatically](references/pencilkit patterns.md constructing strokes programmatically)
only for generated ink paths; ordinary drawing and inspection do not need the
advanced constructors.
SwiftUI Integration
Wrap PKCanvasView in a UIViewRepresentable for SwiftUI.
For SwiftUI wrappers, set the input policy using the canonical
[Drawing Policies]( drawing policies) table.
Usage in SwiftUI
PaperKit Relationship
PaperKit (iOS 26+) extends PencilKit with a complete markup experience
including shapes, text boxes, images, stickers, and loupes. Use the sibling
paperkit skill when you need structured markup rather than only freeform
drawing.
Capability PencilKit PaperKit
Freeform drawing Yes Yes
Shapes & lines No Yes
Text boxes No Yes
Images & stickers No Yes
Loupes No Yes
Markup toolbar No Yes
Markup insertion UI No MarkupEditViewController , MarkupToolbarViewController
Data model PKDrawing PaperMarkup
PaperKit uses PencilKit under the hood: PaperMarkupViewController accepts
PKTool for its drawingTool property, and PaperMarkup can append a
PKDrawing .
Common Mistakes
DON'T: Forget to call becomeFirstResponder for the tool picker
The tool picker only appears when its associated responder is first responder.
DON'T: Create multiple tool pickers for the same canvas
One PKToolPicker per canvas. Creating extras causes visual conflicts.
DON'T: Ignore content versions for backward compatibility
Apply the [Content Version Compatibility]( content version compatibility) gate
to both the canvas and tool picker before syncing editable drawings.
DON'T: Compare drawings by data representation
dataRepresentation() is for persistence and interchange, not comparison.
Use PKDrawing equality for exact value checks, and inspect strokes or rendered
images for visual/approximate comparisons.
Review Checklist
[ ] PKCanvasView.drawingPolicy follows the canonical policy table
[ ] PKToolPicker stored as a property, not recreated each appearance
[ ] canvasView.becomeFirstResponder() called to show the tool picker
[ ] Canvas added as a PKToolPicker observer before showing the picker
[ ] Drawing serialized via dataRepresentation() and loaded via PKDrawing(data:)
[ ] canvasViewDrawingDidChange delegate method used to track changes
[ ] maximumSupportedContentVersion set on both canvas and tool picker if backward compatibility is needed
[ ] Custom tool picker item code guarded for iOS/iPadOS 18+ and visionOS 2+
[ ] Exported images use appropriate scale factor for the device
[ ] SwiftUI wrapper avoids infinite update loops by checking drawing != binding
[ ] Drawing bounds checked before image export (empty drawings have .zero bounds)
References
Extended PencilKit patterns (advanced strokes, content versions, delegates): [references/pencilkit patterns.md](references/pencilkit patterns.md)
[PencilKit framework](https://sosumi.ai/documentation/pencilkit)
[PKCanvasView](https://sosumi.ai/documentation/pencilkit/pkcanvasview)
[PKDrawing](https://sosumi.ai/documentation/pencilkit/pkdrawing swift.struct)
[PKToolPicker](https://sosumi.ai/documentation/pencilkit/pktoolpicker)
[PKInkingTool](https://sosumi.ai/documentation/pencilkit/pkinkingtool swift.struct)
[PKStroke](https://sosumi.ai/documentation/pencilkit/pkstroke swift.struct)
[Drawing with PencilKit](https://sosumi.ai/documentation/pencilkit/drawing with pencilkit)
[Configuring the PencilKit tool picker](https://sosumi.ai/documentation/pencilkit/configuring the pencilkit tool picker)