I'm exploring PDFKit with swiftUI. Here is my sample code to select a pdf file on macOS (that's work). Show a Quicklook that's works fine too and I want to show a view with pdf content with the help of a PDFKitRepresentedView (see at the end of the code).
PDFKitRepresentedView works fine at first file selection but it doesn't work if I select another file. I thing it's a binding problem but I need help to resolve it.
Thanks...
import SwiftUI
import UniformTypeIdentifiers
import QuickLook
import PDFKit
struct FilePickerView: View {
@State var filename = ""
@State var selectFileURL: URL?
@State var previewURL: URL?
var body: some View {
VStack {
HStack {
Text(filename)
Button("Select File")
{
let panel = NSOpenPanel()
panel.allowsMultipleSelection = false
panel.canChooseDirectories = false
panel.allowedContentTypes = [UTType.pdf].compactMap { $0 }
if panel.runModal() == .OK {
self.selectFileURL = panel.url
self.filename = panel.url?.lastPathComponent ?? "<none>"
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
if let p = selectFileURL {
PDFKitRepresentedView(url: p)
}
Button("Preview") {
previewURL = selectFileURL
}.quickLookPreview($previewURL)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
FilePickerView()
}
}
struct PDFKitRepresentedView: NSViewRepresentable {
var url : URL
func makeNSView(context: Context) -> PDFView {
let pdfView = PDFView()
pdfView.document = PDFDocument(url:url)
return pdfView
}
func updateNSView(_ nsView: PDFView, context: Context) { }
}
Right now, you are setting the document (and thus the URL) of the PDFView
inside makeNSView
, which only gets called once when the View
is created. So, if the url
parameter updates, nothing will ever change, since the View
is already created.
You could solve this by using updateNSView
to update the document
parameter of the View
, but if you ever added another parameter, you would risk updating the document
when that other parameter changed as well.
I think this is a reasonable candidate for adding an explicit id
to the PDFKitRepresentedView
-- whenever the id
changes, makeNSView
will get called again since it will be a new View
.
PDFKitRepresentedView(url: p)
.id(p)