sol
sol

Reputation: 1

How do I rerun the PDFPageOverlayViewProvider?

I want to rerun the function pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? in PDFPageOverlayViewProvider. This function is executed when a page is rendered, but I need to update the overlay view using a button. The updated view will only be displayed if the function is rerun. How can I achieve this?

struct PDFKitRepresentableView: UIViewRepresentable {
    let bookId: UUID
    @Binding var selectedNote: [SelectedNote]
    let pdfDocument: PDFDocument
    let pdfView = PDFView()
    let toolPicker = PKToolPicker()
    let setIndex: (String) -> Void
    
    func makeUIView(context: Context) -> PDFView {
        pdfView.displayMode = .singlePageContinuous
        pdfView.usePageViewController(false)
        pdfView.displayDirection = .vertical
        
        pdfView.pageOverlayViewProvider = context.coordinator
        pdfView.autoScales = true
        
        pdfView.document = pdfDocument
        
        NotificationCenter.default.addObserver(
            context.coordinator,
            selector: #selector(context.coordinator.handlePageChange(notification:)),
            name: Notification.Name.PDFViewPageChanged,
            object: nil
        )
        
        pdfView.becomeFirstResponder()
        return pdfView
    }
    
    
    func updateUIView(_ uiView: PDFView, context: Context) {
        let savedDestination = uiView.currentPage
        
        if
            let localNote = selectedNote.first(where: {$0.noteId == bookId.uuidString}),
            !localNote.selected
        {
            toolPicker.setVisible(false, forFirstResponder: uiView)
        } else {
            toolPicker.setVisible(true, forFirstResponder: uiView)
        }
        
        uiView.document = uiView.document
        uiView.layoutDocumentView()
        uiView.setNeedsDisplay()
    }
    
    func makeCoordinator() -> CanvasProvider {
        return CanvasProvider(parent: self)
    }
    
    func setPageLabel(pdfView: PDFView) {
        setIndex(pdfView.currentPage?.label ?? "0")
    }
}


extension CanvasProvider: PDFPageOverlayViewProvider {
    func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {
        let result = UIView()
        
        let defaults = UserDefaults.standard
        let rect = page.bounds(for: .mediaBox)
        let rectData = [
            "originX": rect.origin.x,
            "originY": rect.origin.y,
            "sizeWidth": rect.size.width,
            "sizeHeight": rect.size.height
        ]
        defaults.set(rectData, forKey: "\(parent.bookId.uuidString)_size")
        
        parent.selectedNote.enumerated().forEach { index, note in
            if note.selected {
                if
                    note.noteId == parent.bookId.uuidString,
                    let pkCanvasView = localNote[page]
                {
                    pkCanvasView.backgroundColor = .clear
                    pkCanvasView.isOpaque = true
                    pkCanvasView.drawingPolicy = .anyInput
                    pkCanvasView.delegate = self
                    
                    if note.noteId == parent.bookId.uuidString {
                        parent.toolPicker.addObserver(pkCanvasView)
                    }
                    
                    result.addSubview(pkCanvasView)
                    
                    pkCanvasView.translatesAutoresizingMaskIntoConstraints = false
                    NSLayoutConstraint.activate([
                        pkCanvasView.leadingAnchor.constraint(equalTo: result.leadingAnchor),
                        pkCanvasView.trailingAnchor.constraint(equalTo: result.trailingAnchor),
                        pkCanvasView.topAnchor.constraint(equalTo: result.topAnchor),
                        pkCanvasView.bottomAnchor.constraint(equalTo: result.bottomAnchor)
                    ])
                } else {
                    if let data = passNote[note.noteId]?[page] {
                        let image = UIImage(data: data, scale: 1)!
                        
                        if let page = view.currentPage {
                            page.bounds(for: view.displayBox)
                        }
                        
                        let uiImageView = UIImageView()
                        uiImageView.contentMode = .scaleAspectFill
                        uiImageView.clipsToBounds = true
                        uiImageView.image = image
                        result.addSubview(uiImageView)
                        
                        uiImageView.translatesAutoresizingMaskIntoConstraints = false
                        NSLayoutConstraint.activate([
                            uiImageView.leadingAnchor.constraint(equalTo: result.leadingAnchor),
                            uiImageView.trailingAnchor.constraint(equalTo: result.trailingAnchor),
                            uiImageView.topAnchor.constraint(equalTo: result.topAnchor),
                            uiImageView.bottomAnchor.constraint(equalTo: result.bottomAnchor)
                        ])
                        
                        result.layoutIfNeeded()
                    }
                }
            }
        }
        
        for subView in view.documentView?.subviews ?? [] {
            if subView.theClassName == "PDFPageView" {
                subView.isUserInteractionEnabled = true
            }
        }
        
        return result
    }
}

Upvotes: 0

Views: 38

Answers (0)

Related Questions