Well, a lot of it would depend on exactly how you are having your users select a document to display. Without more info from your code, I can’t really say. But, basically, you would create a PDFDocument from whatever the user selects and then pass it into the UIViewRepresentable-wrapped PDFView.
Here is an updated example showing how to pass in a PDFDocument and set the page to view.
import SwiftUI
import PDFKit
struct TestPDFView: View {
let pdfDoc: PDFDocument
init() {
//this is just for example
//in your app, you would get a document from the user selection somehow
let url = Bundle.main.url(forResource: "Lipsum", withExtension: "pdf")!
//however you get the document from the user,
//convert it into a PDFDocument
pdfDoc = PDFDocument(url: url)!
}
var body: some View {
NavigationView {
List {
Text("Total Page Count: \(pdfDoc.pageCount)")
ForEach(1...pdfDoc.pageCount, id: \.self) { pg in
NavigationLink("Page \(pg)") {
PDFUIView(document: pdfDoc, atPage: pg)
}
}
}
}
}
}
struct PDFUIView: View {
let document: PDFDocument
@State private var currentPage: Int
init(document: PDFDocument, atPage: Int = 1) {
self.document = document
_currentPage = State(initialValue: atPage)
}
var body: some View {
PDFKitView(showing: document, atPage: $currentPage)
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Button {
currentPage -= 1
} label: {
Image(systemName: "chevron.left")
}
.disabled(currentPage == 1)
Button {
currentPage += 1
} label: {
Image(systemName: "chevron.right")
}
.disabled(currentPage == document.pageCount)
}
}
.navigationTitle("Page \(currentPage) of \(document.pageCount)")
.navigationBarTitleDisplayMode(.inline)
}
}
struct PDFKitView: UIViewRepresentable {
let pdfDocument: PDFDocument
let startPage: Binding<Int>
init(showing pdfDoc: PDFDocument, atPage: Binding<Int>) {
self.pdfDocument = pdfDoc
self.startPage = atPage
}
func makeUIView(context: Context) -> PDFView {
let pdfView = PDFView()
pdfView.autoScales = true
pdfView.displayMode = .singlePage
pdfView.document = pdfDocument
//we have to subtract 1 from startPage because page in PDFKit is 0-based
if let page = pdfDocument.page(at: startPage.wrappedValue - 1) {
pdfView.go(to: page)
}
return pdfView
}
func updateUIView(_ pdfView: PDFView, context: Context) {
pdfView.document = pdfDocument
//we have to subtract 1 from startPage because page in PDFKit is 0-based
if let page = pdfDocument.page(at: startPage.wrappedValue - 1) {
pdfView.go(to: page)
}
}
}
Many thanks for the input. I had been using poor architecture and methods. I used your code with minor cosmetic modifications and got it going.
So far, I implemented an information manual in pdf with sections applicable to different views. The info buttons on each view open the manual to the applicable page. This is the initial use of the process, and it has a practical benefit.
But the next step is creation, management, and viewing of pdf reports generated within the app, which is the real reason I want to set this up. Will continue to work on this process, which is easier now that I have your framework. Thanks again for getting me over this snag.