Implement drawing, handwriting, and sketching with PencilKit and PaperKit. Use when integrating PKCanvasView, configuring PKToolPicker, handling drawing gestures and Apple Pencil features, inspecting or rendering strokes, managing drawing data, or building drawing interfaces.
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Integrate drawing, sketching, and annotation into iOS and iPadOS apps using PencilKit (PKCanvasView, PKToolPicker, PKDrawing) and PaperKit. Targets Swift 6.4 / iOS 26+.
| Component | Responsibility |
|---|---|
PKCanvasView | Scrollable drawing canvas that receives touch and pencil inputs; inherits from UIScrollView |
PKToolPicker | Floating system tool palette offering pens, pencils, markers, erasers, rulers, and custom tools |
PKDrawing | Immutable data model containing vector strokes (PKStroke), stroke points, and bounds |
PKTool | Active drawing instrument (PKInkingTool, PKEraserTool, PKLassoTool) |
PKCanvasViewDelegate | Notifies when drawing changes or user starts/ends drawing |
Bridge PKCanvasView into SwiftUI using UIViewRepresentable:
import SwiftUI
import PencilKit
struct CanvasViewRepresentable: UIViewRepresentable {
@Binding var drawing: PKDrawing
var tool: PKTool = PKInkingTool(.pen, color: .black, width: 5)
var isRulerActive: Bool = false
func makeUIView(context: Context) -> PKCanvasView {
let canvas = PKCanvasView()
canvas.drawingPolicy = .anyInput
canvas.tool = tool
canvas.isRulerActive = isRulerActive
canvas.delegate = context.coordinator
return canvas
}
func updateUIView(_ uiView: PKCanvasView, context: Context) {
if uiView.drawing != drawing {
uiView.drawing = drawing
}
uiView.tool = tool
uiView.isRulerActive = isRulerActive
}
func makeCoordinator() -> Coordinator { Coordinator(self) }
class Coordinator: NSObject, PKCanvasViewDelegate {
var parent: CanvasViewRepresentable
init(_ parent: CanvasViewRepresentable) { self.parent = parent }
func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
Task { @MainActor in parent.drawing = canvasView.drawing }
}
}
}drawing.dataRepresentation(). Restore via PKDrawing(data:).drawing.image(from: canvasView.bounds, scale: canvasView.traitCollection.displayScale).drawing.strokes to inspect points, pressure, force, and azimuth.Configure canvasView.drawingPolicy:
.default: Follows system preference (Apple Pencil only if configured in Settings)..anyInput: Allows finger drawing alongside Apple Pencil..pencilOnly: Restricts drawing strictly to Apple Pencil; finger touches scroll the canvas.Coordinating PKToolPicker: Attach the picker with toolPicker.setVisible(true, forFirstResponder: canvasView) and toolPicker.addObserver(canvasView). Ensure the canvas becomes first responder.
PKToolPicker (iOS 18+), read Custom Tool Picker Items.UndoManager, read Undo/Redo Support.__PKStrokeRenderState is renamed PKStrokeRenderStateReference. Its initializer replaces PKStrokeRenderState.asObjCRenderState().Sources: https://sosumi.ai/documentation/ios-ipados-release-notes/ios-ipados-27-release-notes
canvasView.becomeFirstResponder() before showing PKToolPicker.@Binding var drawing continuously during drawing gestures, causing hitching and feedback loops.drawingPolicy = .pencilOnly.PKToolPicker floats automatically in SwiftUI without anchoring to a window or first responder.PKCanvasView embedded in SwiftUI with a clean CoordinatordrawingPolicy explicitly set (.anyInput, .pencilOnly, or .default)PKToolPicker tied to canvas first responder and visible statedataRepresentation() and restored with error handlingundoManagerPKToolPicker obscures canvas regionsthienqo/ios-skills
6bf8b62
Canonical home
since May 23, 2026
Also appears in
on Oct 29, 2026
since May 22, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.