Search code examples
swiftpdfswiftuipdfkitpencilkit

SWIFTUI: Draw on a PDF


so I'm building an app right now where I want to draw on a PDF - just like a signature.

The app is build in Swift and I'm using SwiftU, PencilKit, PDFKit and WebKit. I already can show the PDF and draw on view. If I use my PDFView as a background for my PencilKitCanvas I can basically draw on that PDF but I don't think this is the way to go. Also I cannot save the new PDF this way.

ZStack {
            Image("background")
                .resizable()
                .edgesIgnoringSafeArea(.all)

            VisualEffectView(effect: UIBlurEffect(style: .light))
                .edgesIgnoringSafeArea(.all)
        VStack {

            
            if isPDFLoading == true {
                ActivityIndicator().frame(width: 150, height: 150)
            } else {
                
                PKCanvasRepresentation().background(PDFView(request: PDFPath)).edgesIgnoringSafeArea(.bottom)
            }

        }
        
    }

This is my View and these are my PDF and PencilKitCanvasViews:

struct PDFView: UIViewRepresentable {
    let request: URLRequest

    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(self.request)
    }
}

...

    func setupDrawing() {
        let canvasView = PKCanvasView(frame: self.view.bounds)
        guard let window = view.window, let toolPicker = PKToolPicker.shared(for: window) else {
            return
        }
        toolPicker.setVisible(true, forFirstResponder: canvasView)
        toolPicker.addObserver(canvasView)
        canvasView.backgroundColor = .clear
        canvasView.becomeFirstResponder()
        view.addSubview(canvasView)
    }
}

/// Converts ViewController into a view for SwiftUI
struct PKCanvasRepresentation: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> PKCanvasViewController {
        return PKCanvasViewController()
    }

    func updateUIViewController(_ uiViewController: PKCanvasViewController, context: Context) {

    }

    typealias UIViewControllerType = PKCanvasViewController

}

So how can I exactly draw on a PDF and save it? Do I have to save it all as a UIImage and convert it into a PDF?

Thanks and excuse my bad english.


Solution

  • Take a look at this tutorial: https://medium.com/better-programming/ios-pdfkit-ink-annotations-tutorial-4ba19b474dce

    It is just a little bit hacky but it records the drawings directly as PDF Annotations that can be saved with the PDF. The PDF must not be secured in order to alter it.

    PencilKit is very nice for the low latency drawing and built-in set of features. You would save the drawing separately as a PKDrawing which is pretty convenient. PKDrawing doesn't allow you to store bitmaps (text from a textbox for example).