-0.7 C
New York
Saturday, February 1, 2025

ios – The PKCanvasView Created by PDFPageOverlayViewProvider can not work usually


By setting the PKCanvasView background colour to blue, I can inform that the PKCanvasView for every PDFPage is created usually, however it doesn’t reply to the touch. Particularly, whether or not it’s finger or applepencil, all of the responses of the web page happen from PDFView(reminiscent of zoom and scroll), and PKCanvasView can’t draw, please how one can clear up?

struct PDFContentView: UIViewControllerRepresentable {
    let file: FileItem
    @Binding var selectedPage: Int
    @Binding var currentMode: Mode
    @Binding var latestPdfChatResponse: LatestPDFChatResponse
    @Binding var drawDataList: [DrawDataItem]
    
    @ObservedObject var userMessage: ChatMessage
    @EnvironmentObject var userSettings: UserSettings
    
    func makeUIViewController(context: Context) -> PDFAnnotatableViewController {
        let controller = PDFAnnotatableViewController(
            file: file,
            userSettings: userSettings,
            drawDataList: $drawDataList,
            selectedPage: $selectedPage,
            currentMode: $currentMode,
            latestPdfChatResponse: $latestPdfChatResponse,
            userMessage: userMessage
        )
        return controller
    }

    func updateUIViewController(_ uiViewController: PDFAnnotatableViewController, context: Context) {
        uiViewController.goToPage(selectedPage: selectedPage-1)
        uiViewController.togglecurrentMode(currentMode: currentMode)
    }
}

class PDFAnnotatableViewController: UIViewController, PDFViewDelegate {
    personal let pdfView = PDFView()
    personal var pdfDocument: PDFDocument?
    
    let file: FileItem
    personal var userSettings: UserSettings
    @Binding var selectedPage: Int
    @Binding var currentMode: Mode
    @Binding var latestPdfChatResponse: LatestPDFChatResponse
    @State personal var pdfPageCoordinator = PDFPageCoordinator()
    @ObservedObject var userMessage: ChatMessage
    
    init(file: FileItem,
         userSettings: UserSettings,
         drawDataList:  Binding<[DrawDataItem]>,
         selectedPage: Binding,
         currentMode: Binding,
         latestPdfChatResponse: Binding,
         userMessage: ChatMessage) {
        
        self.file = file
        self.userSettings = userSettings
        self._selectedPage = selectedPage
        self._currentMode = currentMode
        self._latestPdfChatResponse = latestPdfChatResponse
        self.userMessage = userMessage
        tremendous.init(nibName: nil, bundle: nil)
        
        DispatchQueue.world(qos: .userInitiated).async {
            if let doc = PDFDocument(url: file.pdfLocalUrl) {
                DispatchQueue.predominant.async {
                    self.pdfDocument = doc
                    self.pdfView.doc = doc
                    self.goToPage(selectedPage: selectedPage.wrappedValue - 1)
                }
            } else {
                print("❌ PDF 文档加载失败")
            }
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been carried out")
    }
    
    override func viewDidLoad() {
        tremendous.viewDidLoad()
        setupPDFView()
    }
    
    // MARK: - PDF
    personal func setupPDFView() {
        pdfView.delegate = self
        pdfView.autoScales = true
        pdfView.displayMode = .singlePage
        pdfView.displayDirection = .vertical
        pdfView.backgroundColor = .white
        pdfView.usePageViewController(true)
        pdfView.displaysPageBreaks = false
        pdfView.displaysAsBook = false
        pdfView.minScaleFactor = 0.8
        pdfView.maxScaleFactor = 3.5
        pdfView.pageOverlayViewProvider = pdfPageCoordinator
        
        if let doc = pdfDocument {
            pdfView.doc = doc
            goToPage(selectedPage: selectedPage)
        }
        
        pdfView.body = view.bounds
        pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(pdfView)
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handlePageChange),
            identify: .PDFViewPageChanged,
            object: pdfView
        )
    }

    // Coping with web page turning
    @objc personal func handlePageChange(notification: Notification) {
        guard let currentPage = pdfView.currentPage, let doc = pdfView.doc else { return }
        let currentPageIndex = doc.index(for: currentPage)
        
        if currentPageIndex != selectedPage - 1 {
            DispatchQueue.predominant.async {
                self.selectedPage = currentPageIndex + 1
            }
        }
    }
    

    func goToPage(selectedPage: Int) {
        guard let doc = pdfView.doc else { return }
        if let web page = doc.web page(at: selectedPage) {
            pdfView.go(to: web page)
        }
    }
    
    // Change operate
    func togglecurrentMode(currentMode: Mode){
        DispatchQueue.predominant.async {
            
            if self.currentMode == .none{
                self.pdfView.usePageViewController(true)
                self.pdfView.isUserInteractionEnabled = true
            } else if self.currentMode == .annotation {
                if let web page = self.pdfView.currentPage {
                    if let canvasView = self.pdfPageCoordinator.getCanvasView(forPage: web page) {
                        canvasView.isUserInteractionEnabled = true
                        canvasView.instrument = PKInkingTool(.pen, colour: .crimson, width: 20) // 设置绘画工具
                        canvasView.drawingPolicy = .anyInput  // 支持所有输入,包括 Apple Pencil
                        canvasView.setNeedsDisplay()
                    }
                }
            }
        }
    }
}

class MyPDFPage: PDFPage {
    var drawing: PKDrawing?
    
    func setDrawing(_ drawing: PKDrawing) {
        self.drawing = drawing
    }
    
    func getDrawing() -> PKDrawing? {
        return self.drawing
    }
}

class PDFPageCoordinator: NSObject, PDFPageOverlayViewProvider {
    
    var pageToViewMapping = [PDFPage: PKCanvasView]()
    
    func pdfView(_ view: PDFView, overlayViewFor web page: PDFPage) -> UIView? {
        var resultView: PKCanvasView? = nil
        
        if let overlayView = pageToViewMapping[page] {
            resultView = overlayView
        } else {
            let canvasView = PKCanvasView(body: view.bounds)
            canvasView.drawingPolicy = .anyInput
            canvasView.instrument = PKInkingTool(.pen, colour: .systemYellow, width: 20)
            canvasView.backgroundColor = .blue
            pageToViewMapping[page] = canvasView
            resultView = canvasView
        }
        
        if let web page = web page as? MyPDFPage, let drawing = web page.drawing {
            resultView?.drawing = drawing
        }
        return resultView
    }
    
    func pdfView(_ pdfView: PDFView, willEndDisplayingOverlayView overlayView: UIView, for web page: PDFPage) {
        guard let overlayView = overlayView as? PKCanvasView, let web page = web page as? MyPDFPage else { return }
        web page.drawing = overlayView.drawing
        pageToViewMapping.removeValue(forKey: web page)
    }
    
    func savePDFDocument(_ pdfDocument: PDFDocument) -> Knowledge {
        for i in 0.. PKCanvasView? {
        return pageToViewMapping[page]
    }
}

Is there an error in my code? Please inform me how one can make PKCanvasView portray usually?

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles