Search code examples
swiftswiftuiuikit

The PDFPageOverlayProvider Coordinator's methods never get called in PDFKit, SwiftUI


I am trying to integrate PencilKit on a PDFKit view in SwiftUI, but the coordinators delegate methods never trigger. What I am doing wrong here ?

import SwiftUI
import PDFKit
import PencilKit

struct PDFDocumentView: View {
    var url: URL?
    
    var body: some View {
        if let pdfURL = url {
            let pdfDocument = PDFDocument(url: pdfURL)
            if let pdf = pdfDocument {
                PDFViewWrapper(pdfDocument: pdf)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .edgesIgnoringSafeArea(.all)
            }
        }
    }
}

struct PDFViewWrapper: UIViewControllerRepresentable {
    var pdfDocument: PDFDocument
    var coordinator: OverlayCoordinator = OverlayCoordinator()
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<PDFViewWrapper>) -> some UIViewController {
        let pdfView  = PDFView()
        pdfView.document = pdfDocument
        pdfView.pageOverlayViewProvider = coordinator
        pdfView.delegate = coordinator
        pdfView.isInMarkupMode = true
        
        let viewController = UIViewController()
        viewController.view.addSubview(pdfView)
        pdfView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([pdfView.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor),
                                     pdfView.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor),
                                     pdfView.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor),
                                     pdfView.topAnchor.constraint(equalTo: viewController.view.topAnchor)])
        return viewController
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: UIViewControllerRepresentableContext<PDFViewWrapper>) {}
}`

`class OverlayCoordinator : NSObject, PDFPageOverlayViewProvider , PDFViewDelegate {
    var pageToViewMapping = [PDFPage: PKCanvasView]() // Change UIView to PKCanvasView
    
    func pdfView(_ pdfView: PDFView, willDisplayOverlayView overlayView: UIView, for page: PDFPage) {
        print("here")
    }

    func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {
        print("Setup Overlay View ")
        if let canvasView = pageToViewMapping[page] {
            return canvasView
        } else {
            let canvasView = PKCanvasView(frame: .zero)
            canvasView.backgroundColor = UIColor.clear
            canvasView.drawingPolicy = .anyInput
            canvasView.tool = PKInkingTool(ink: .init(.pen), width: 90)
            canvasView.isOpaque = false
            pageToViewMapping[page] = canvasView
            return canvasView
        }
    }
}

#Preview {
    PDFDocumentView()
}

Solution

  • Setting:

    pdfView.pageOverlayViewProvider = coordinator
    

    should be done before:

    pdfView.document = pdfDocument