Swift UI 和 PDFKit - 如何以编程方式更新我的页面?

Swift UI and PDFKit - How do I update my page programmatically?

我想在当前页面的状态通过按钮更改时更新视图。 在控制台中点击使当前页面相应增加。

我尝试使用 gotoNextPage()(解决方案 2)但它不起作用 并尝试使用 go to 方法。(解决方案 1) 即使打印的值看起来没问题,它们也没有更新。

PDFVIEW CurrentPage value is:Optional(<PDFPage: 0x281917b60> page index 203)

有什么解决办法吗?

@State var pdfName: String
@State var start: Int

PDFKitView(url: Bundle.main.url(forResource: pdfName, withExtension: "pdf")!, currentPage: start)
import SwiftUI  
import PDFKit

struct PDFKitView: View {
    var url: URL
    var currentPage: Int
    
    var body: some View {
        PDFKitRepresentedView(url, currentPage)
    }
}

struct PDFKitRepresentedView: UIViewRepresentable {
    let url: URL
    let currentPage: Int
    let pdfView = PDFView()

    init(_ url: URL, _ currentPage: Int) {
        self.url = url
        self.currentPage = currentPage
    }

    func makeUIView(context: UIViewRepresentableContext<PDFKitRepresentedView>) -> PDFKitRepresentedView.UIViewType {
        print("PDFVIEW IS CREATED")
        pdfView.document = PDFDocument(url: self.url)
        pdfView.displayMode = .singlePage
        pdfView.displayDirection = .horizontal
        pdfView.autoScales = true
        pdfView.usePageViewController(true)
        pdfView.go(to: pdfView.document!.page(at: currentPage)!)
        
        let total = pdfView.document?.pageCount
        print("Total pages: \(total ?? 0)")
        return pdfView
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PDFKitRepresentedView>) {
        // Update the view.
             
        //THIS IS PRINTED IN CONSOLE EVERY TIME  
        print("PDFVIEW IS UPDATED")
        print("CurrentPage value is:\(currentPage)")
        
        //SOLUTION TRIED 1. SAME CODE WORKS ON makeUIView: I can see the pdf, scroll it     and zoom. Also let it start at any page I want to. But not here.
        print("PDFVIEW IS UPDATED")
        print("CurrentPage value is:\(currentPage)")
        
        //SOLUTION 1
        pdfView.document = PDFDocument(url: self.url)
        pdfView.displayMode = .singlePage
        pdfView.displayDirection = .horizontal
        pdfView.autoScales = true
        pdfView.usePageViewController(true)
        pdfView.go(to: pdfView.document!.page(at: currentPage)!)
        print("PDFVIEW CurrentPage value is:\(pdfView.currentPage)")

        /*

        PDFVIEW IS UPDATED
        CurrentPage value is:203
        PDFVIEW CurrentPage value is:Optional(<PDFPage: 0x281917b60> page index 203)
        */
      
        //SOLUTION TRIED 2
        //goToNextPage()
    }
    
    func goToNextPage(){
        pdfView.goToNextPage(nil)
    }
}

真相的来源应该在外面的某个地方,并通过内部绑定或其他可观察类型注入。

这里是简化的固定变体。使用 Xcode 13.4 / iOS 15.5

测试

主要部分:

    func makeUIView(context: Context) -> UIView {
        guard let document = PDFDocument(url: self.url) else { return UIView() }

        let pdfView = PDFView()
        print("PDFVIEW IS CREATED")
        pdfView.document = document
        pdfView.displayMode = .singlePage
        pdfView.displayDirection = .horizontal
        pdfView.autoScales = true
        pdfView.usePageViewController(true)

        DispatchQueue.main.async {
            self.total = document.pageCount
            print("Total pages: \(total)")
        }
        return pdfView
    }

    func updateUIView(_ uiView: UIView, context: Context) {
        guard let pdfView = uiView as? PDFView else { return }

        if currentPage < total {
            pdfView.go(to: pdfView.document!.page(at: currentPage)!)
        }
    }

注意:处理 PDFView 通过滑动委托导航以传回绑定是你的事。

Complete test module is here