NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

PencilKit with SwiftUI

Forums > SwiftUI

Hi all,

I was trying to figure out how to get a UIViewRepresentable of a PKCanvasView to work in SwiftUI with the ability for a parent view to manage undo and redo functionality. I spent a few days of research and found a solution that seems to work well. I wanted to post this here in case this can help someone in the future!

Here's the parent view that uses the environment UndoManager:

struct Writer: View {
    @Environment(\.undoManager) private var undoManager
    @State private var canvasView = PKCanvasView()

    var body: some View {
        VStack(spacing: 10) {
            Button("Clear") {
                canvasView.drawing = PKDrawing()
            }
            Button("Undo") {
                undoManager?.undo()
            }
            Button("Redo") {
                undoManager?.redo()
            }
            MyCanvas(canvasView: $canvasView)
        }
    }
}

Here's the PKCanvasView wrapped UIViewRepresentable:

struct MyCanvas: UIViewRepresentable {
    @Binding var canvasView: PKCanvasView

    func makeUIView(context: Context) -> PKCanvasView {
        canvasView.drawingPolicy = .anyInput
        canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
        return canvasView
    }

    func updateUIView(_ canvasView: PKCanvasView, context: Context) { }
}

Initially I tried various things using coordinators and PKCanvasViewDelegate functions. In the end, the solution is very simple and straightforward. In hindsight, I feel almost foolish for how long it took me to get this working. Hopefully this will prevent a future headache for someone else!

edit: I found that my original solution broke with iOS 14. Adding canvasView.drawingPolicy = .anyInput seemed to have fixed the problem.

16      

Hacking with Swift is sponsored by MadMachine

SPONSORED Want to explore your Swift skill outside of the Apple world? Join the MadMachine community and start to program microcontrollers in Swift.

Get it now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.