如何在 swiftui pdf 中以编程方式更改页面

How to change the page programmicly in swiftui pdf

我有显示 pdf 的代码

  import PDFKit
import SwiftUI

struct PDFKitRepresentedView: UIViewRepresentable {
    typealias UIViewType = PDFView

    let data: Data
    let singlePage: Bool
    var doc:PDFView=PDFView()
    init(_ data: Data, singlePage: Bool = false) {
        self.data = data
        self.singlePage = singlePage
    }

    func makeUIView(context _: UIViewRepresentableContext<PDFKitRepresentedView>) -> UIViewType {
        // Create a `PDFView` and set its `PDFDocument`.
        let pdfView = doc
        pdfView.document = PDFDocument(data: data)
        pdfView.autoScales = true
        if singlePage {
            pdfView.displayMode = .singlePage
        }
        return pdfView
    }
    
    func updateUIView(_ pdfView: UIViewType, context _:                  UIViewRepresentableContext<PDFKitRepresentedView>) {
        pdfView.document = PDFDocument(data: data)
        
      }
    }
    struct ContentView: View {
     var path=Bundle.main.url(forResource: "big", withExtension:  "pdf");
     @State var doc:PDFKitRepresentedView=PDFKitRepresentedView(Data())
     @State var data :Data?;
     var body: some View {
        HStack{
            start(doc: &doc,path: path!)
                .onAppear(perform: {
                    self.data=try?Data(contentsOf: path!);
                    doc.doc.goToNextPage(nil)
                    doc.doc.goToNextPage(nil)
                })
        }
        }
    }

    func start(doc:inout PDFKitRepresentedView,path:URL)->PDFKitRepresentedView{
      doc=try!PDFKitRepresentedView(Data(contentsOf: path));
      return doc;
    }

但我似乎无法在显示中找到更改页面的方法 pdf.I 尝试了 go() 但它只是崩溃了。我需要一个按钮来更改页面 click.Sorry 我是 swiftUI 的新手。

您可以 re-structure 您的代码并使用以下方法将 Buttons 中的页面选择添加到 func updateUIView(...) 中:

import PDFKit
import SwiftUI

struct PDFKitView: UIViewRepresentable {
    typealias UIViewType = PDFView
    
    @Binding var page: Int
    @State var data: Data
    let singlePage: Bool
    
    func makeUIView(context: UIViewRepresentableContext<PDFKitView>) -> UIViewType {
        let pdfView = PDFView()
        pdfView.document = PDFDocument(data: data)
        pdfView.autoScales = true
        if singlePage {
            pdfView.displayMode = .singlePage
        }
        return pdfView
    }

    func updateUIView(_ view: UIViewType, context: UIViewRepresentableContext<PDFKitView>) {
        if let thePage = view.document?.page(at: page) {
            view.go(to: thePage)
        }
    }
}

struct ContentView: View {
    @State var page = 0
    
    var body: some View {
        VStack {
            HStack {
                Button("Next Page") { page += 1 } // need to add bounds check
                Button("Prev Page") { page -= 1 } // need to add bounds check
            }.buttonStyle(.bordered)
            PDFKitView(page: $page, data: loadData(), singlePage: true)
        }
    }
    
    private func loadData() -> Data {
        guard let path = Bundle.main.url(forResource: "big", withExtension:  "pdf") else {
            print("Could not find PDF document")
            return Data()
        }
        do {
            return try Data(contentsOf: path)
        } catch {
            print("error: \(error)") // todo
            return Data()
        }
    }
}

编辑-1:

另一种更灵活的方法是将PDFDocument传递给PDFKitView,例如:

struct PDFKitView: UIViewRepresentable {
    typealias UIViewType = PDFView
    
    @Binding var page: Int
    @Binding var doc: PDFDocument
    let singlePage: Bool
    
    func makeUIView(context: UIViewRepresentableContext<PDFKitView>) -> UIViewType {
        let pdfView = PDFView()
        pdfView.document = doc
        pdfView.autoScales = true
        if singlePage {
            pdfView.displayMode = .singlePage
        }
        return pdfView
    }

    func updateUIView(_ view: UIViewType, context: UIViewRepresentableContext<PDFKitView>) {
        view.document = doc
        if let thePage = view.document?.page(at: page) {
            view.go(to: thePage)
        }
    }
}

struct ContentView: View {
    @State var page = 0
    @State var doc = PDFDocument()
    
    var body: some View {
        VStack {
            HStack {
                Button("Next Page") {
                    if page + 1 < doc.pageCount {
                        page += 1
                    }
                }
                Button("Prev Page") {
                    if page-1 > 0 {
                        page -= 1
                    }
                }
            }.buttonStyle(.bordered)
            PDFKitView(page: $page, doc: $doc, singlePage: true)
        }
        .onAppear {
            loadDoc()
        }
    }
    
    private func loadDoc() {
        guard let path = Bundle.main.url(forResource: "big", withExtension: "pdf") else {
            print("Could not find PDF document")
            return
        }
        do {
            let data = try Data(contentsOf: path)
            if let theDoc = PDFDocument(data: data) {
                doc = theDoc
            }
        } catch {
            print("error: \(error)") // todo
        }
    }
}