IOS Pdf 套件墨迹注释在清除后会重新出现。一旦清除,旧注释就不会出现

问题描述 投票:0回答:1

我的

swiftui
视图中有三个按钮..

  1. clear(清除当前页面);
  2. 全部清除;
  3. 提交。

当用户对 pdf 进行注释(墨水)并清除注释,然后决定再次绘制(注释)时。被清除的旧注释重新出现。我不希望旧的注释被清除后再次出现。

清除所有功能也面临同样的错误。

一旦页面注释清晰,旧的注释就不应该出现。 一旦所有注释被清除,旧注释就不会出现。

在我的另一个视图中,我使用按下按钮时的 pdf 容器显示 pdf,我调用以下函数:

清除全部:self.myLocalCoordinator?.removeAllAnnotations()

清除:self.myLocalCoordinator?.removeAnnotationsOnCurrentPage()

提交: if let base64PDF = myLocalCoordinator?.savePDFWithAnnotations() { print("PDF 签名和注释:(base64PDF)")

                        }

我的本地协调员?在我看来,这只是对从完成处理程序中获得的协调器类的引用。

以下是我尝试过的:


import SwiftUI
import PDFKit
import PencilKit
import UIKit


struct PDFViewContainerMulti: UIViewRepresentable {

    var base64Data: String

    @Binding var currentPageIndex: Int

    var completionHandler: (Int, Coordinator) -> Void

    let pdfView = PDFView()

   // var coordinator : Coordinator

    func makeUIView(context: Context) -> PDFView {
       
        
        pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        if let data = Data(base64Encoded: base64Data) {
            if let pdfDocument = PDFDocument(data: data) {
                pdfView.document = pdfDocument
                pdfView.autoScales = true
                //pdfView.displayMode = .singlePageContinuous
                pdfView.displayMode = .singlePage

                // Enable user interactions to allow annotation
                //pdfView.isUserInteractionEnabled = false



                let totalNumberOfPages = pdfDocument.pageCount

                print("The total pages in the pdf document is : \(totalNumberOfPages)")

                completionHandler(pdfDocument.pageCount,Coordinator(parent: self))
                if currentPageIndex < pdfDocument.pageCount {
                                    pdfView.go(to: pdfDocument.page(at: currentPageIndex)!)
                                }

                // Set up gesture recognizer for drawing
                let panGestureRecognizer = UIPanGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handlePanGesture(_:)))
                pdfView.addGestureRecognizer(panGestureRecognizer)
            }
        }

        if let scrollView = pdfView.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView {
                scrollView.isScrollEnabled = false // Disable default scrolling
            }

   //  context.coordinator.pdfView = pdfView
      //  coordinator.pdfView =  context.coordinator.pdfView
        
        PdfView().pdfView = pdfView

        return pdfView
    }

    func updateUIView(_ pdfView: PDFView, context: Context) {
        // Update the view if needed

        if currentPageIndex < pdfView.document?.pageCount ?? 0 {
                    pdfView.go(to: pdfView.document!.page(at: currentPageIndex)!)
                }

    }

    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }






}

class Coordinator: NSObject, ObservableObject {
    var parent: PDFViewContainerMulti
    var allPathsDict: [PDFPage: [UIBezierPath]] = [:]
    var shouldDraw = false
    
    var pdfView: PDFView?

    init(parent: PDFViewContainerMulti) {
        self.parent = parent
       self.pdfView = parent.pdfView
    }

//    @objc func handlePanGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
//        let location = gestureRecognizer.location(in: gestureRecognizer.view)
//
//        if let pdfView = gestureRecognizer.view as? PDFView {
//            if let currentPage = pdfView.page(for: location, nearest: true) {
//                let convertedPoint = pdfView.convert(location, to: currentPage)
//
//                switch gestureRecognizer.state {
//                case .began:
//                    shouldDraw = isPointWithinDrawingArea(convertedPoint, in: currentPage, of: pdfView)
//                    if shouldDraw {
//                        var paths = allPathsDict[currentPage] ?? []
//                        let currentPath = UIBezierPath()
//                        currentPath.move(to: convertedPoint)
//                        paths.append(currentPath)
//                        allPathsDict[currentPage] = paths
//
//                        let annotation = PDFAnnotation(bounds: currentPage.bounds(for: pdfView.displayBox), forType: .ink, withProperties: nil)
//                        annotation.color = UIColor.blue.withAlphaComponent(0.9)
//                        annotation.add(currentPath)
//                        currentPage.addAnnotation(annotation)
//                    }
//                case .changed:
//                    if shouldDraw {
//                        if let paths = allPathsDict[currentPage], let currentPath = paths.last {
//                            currentPath.addLine(to: convertedPoint)
//
//                            currentPage.annotations.forEach { currentPage.removeAnnotation($0) }
//
//                            let updatedAnnotation = PDFAnnotation(bounds: currentPage.bounds(for: pdfView.displayBox), forType: .ink, withProperties: nil)
//                            updatedAnnotation.color = UIColor.blue.withAlphaComponent(0.9)
//                            paths.forEach { updatedAnnotation.add($0) }
//                            currentPage.addAnnotation(updatedAnnotation)
//                            
//                           // savePDFWithAnnotations()
//
//                        }
//                    }
//                    
//                    
//                default:
//                    shouldDraw = false
//                    break
//                }
//            }
//        }
//    }
    
    
    @objc func handlePanGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
        let location = gestureRecognizer.location(in: gestureRecognizer.view)

        if let pdfView = gestureRecognizer.view as? PDFView {
            if let currentPage = pdfView.page(for: location, nearest: true) {
                let convertedPoint = pdfView.convert(location, to: currentPage)

                switch gestureRecognizer.state {
                case .began:
                    shouldDraw = isPointWithinDrawingArea(convertedPoint, in: currentPage, of: pdfView)
                    if shouldDraw {
                        // Create a new path for the current annotation
                        var paths = allPathsDict[currentPage] ?? []
                        let currentPath = UIBezierPath()
                        currentPath.move(to: convertedPoint)
                        paths.append(currentPath)
                        allPathsDict[currentPage] = paths
                        
                        

                        // Add a new annotation
                        let annotation = PDFAnnotation(bounds: currentPage.bounds(for: pdfView.displayBox), forType: .ink, withProperties: nil)
                        annotation.color = UIColor.blue.withAlphaComponent(0.9)
                        annotation.add(currentPath)
                        currentPage.addAnnotation(annotation)
                    }
                case .changed:
                    if shouldDraw {
                        if let paths = allPathsDict[currentPage], let currentPath = paths.last {
                            currentPath.addLine(to: convertedPoint)

                            currentPage.annotations.forEach { currentPage.removeAnnotation($0) }

                            let updatedAnnotation = PDFAnnotation(bounds: currentPage.bounds(for: pdfView.displayBox), forType: .ink, withProperties: nil)
                            updatedAnnotation.color = UIColor.blue.withAlphaComponent(0.9)
                            paths.forEach { updatedAnnotation.add($0) }
                            currentPage.addAnnotation(updatedAnnotation)
                        }
                    }
                default:
                    shouldDraw = false
                    break
                }
            }
        }
    }

    
    

    func isPointWithinDrawingArea(_ point: CGPoint, in page: PDFPage, of pdfView: PDFView) -> Bool {
        let drawingArea = CGRect(x: 0, y: 0, width: pdfView.bounds.width, height: pdfView.bounds.height * 0.9)
        return drawingArea.contains(point)
    }

    func clearDrawing() {
        guard let pdfView = self.pdfView, let currentPage = pdfView.currentPage else { return }

        let paths = allPathsDict[currentPage] ?? []

        paths.forEach { path in
            let annotation = PDFAnnotation(bounds: currentPage.bounds(for: pdfView.displayBox), forType: .ink, withProperties: nil)
            annotation.color = UIColor.blue.withAlphaComponent(0.9)
            annotation.add(path)
            currentPage.addAnnotation(annotation)
        }

        allPathsDict[currentPage]?.removeAll()
    }


    func savePDFWithAnnotations() -> String? {
        guard let pdfView = self.pdfView else {
                            return nil
                        }

        let newPdfDocument = PDFDocument()

        for i in 0..<(pdfView.document!.pageCount ?? 0) {
            if let originalPage = pdfView.document?.page(at: i) {
                let newPage = PDFPage(image: originalPage.thumbnail(of: CGSize(width: originalPage.bounds(for: pdfView.displayBox).width, height: originalPage.bounds(for: pdfView.displayBox).height), for: pdfView.displayBox))!


                    if let paths = allPathsDict[originalPage], paths.count > 0 {
                        let annotation = PDFAnnotation(bounds: originalPage.bounds(for: pdfView.displayBox), forType: .ink, withProperties: nil)
                        annotation.color = UIColor.blue.withAlphaComponent(0.9)
                        paths.forEach { annotation.add($0) }
                        newPage.addAnnotation(annotation)
                    }

                    newPdfDocument.insert(newPage, at: i)
                }
            }

        // Save the new PDF document with annotations
//        if let data = newPdfDocument.dataRepresentation() {
//                let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
//                let pdfURL = documentsDirectory.appendingPathComponent("annotatedPDF.pdf")
//
//                do {
//                    try data.write(to: pdfURL)
//                    print("PDF with annotations saved at: \(pdfURL)")
//                } catch {
//                    print("Error saving PDF with annotations: \(error.localizedDescription)")
//                }
//        }
        
        
        // saving the pdf as base64 string
        
        if let data = newPdfDocument.dataRepresentation() {
                let base64String = data.base64EncodedString()
                return base64String
            }
        
        
        

            return nil
        
        
    }

    
    
    func clearLastAnnotation() {
            guard let pdfView = self.pdfView else { return }

            if let currentPage = pdfView.currentPage,
               var paths = allPathsDict[currentPage],
               let lastPath = paths.popLast() {

                allPathsDict[currentPage] = paths

                currentPage.annotations.forEach { currentPage.removeAnnotation($0) }

                let updatedAnnotation = PDFAnnotation(bounds: currentPage.bounds(for: pdfView.displayBox), forType: .ink, withProperties: nil)
                updatedAnnotation.color = UIColor.blue.withAlphaComponent(0.9)
                paths.forEach { updatedAnnotation.add($0) }
                currentPage.addAnnotation(updatedAnnotation)

               
            }
        }

    

    
    
    func removeAllAnnotations() {
        guard let pdfView = self.pdfView else { return }

        for index in 0..<(pdfView.document?.pageCount ?? 0) {
            if let page = pdfView.document?.page(at: index) {
                let existingAnnotations = page.annotations
                existingAnnotations.forEach { page.removeAnnotation($0) }
                allPathsDict[page]?.removeAll()
            }
        }

        if let currentPage = pdfView.currentPage {
            allPathsDict[currentPage]?.removeAll()
        }
    }
    
    
    func removeAnnotationsOnCurrentPage() {
            guard let pdfView = self.pdfView, let currentPage = pdfView.currentPage else { return }

            currentPage.annotations.forEach { annotation in
                currentPage.removeAnnotation(annotation)
            }

            allPathsDict[currentPage] = []
        }
    


}
ios swift swiftui annotations pdfkit
1个回答
0
投票

清晰的注释: 在您的clearDrawing()方法中,您将清除的注释添加回currentPage。相反,您应该从 currentPage 中删除注释并清除 allPathsDict 中的相应路径。修改您的clearDrawing()方法如下:

func clearDrawing() {
    guard let pdfView = self.pdfView, let currentPage = pdfView.currentPage else { return }

    currentPage.annotations.forEach { annotation in
        currentPage.removeAnnotation(annotation)
    }

    allPathsDict[currentPage]?.removeAll()
}

确保正确初始化: 确保您正在初始化 allPathsDict 并在需要时正确清除它。在协调器的初始化中,您可以清除所有路径:

init(parent: PDFViewContainerMulti) {
    self.parent = parent
    self.pdfView = parent.pdfView
    // Clear all paths when the Coordinator is initialized
    self.allPathsDict.removeAll()
}
© www.soinside.com 2019 - 2024. All rights reserved.