我尝试在 swiftui 中制作简单的 pdf 查看器。当我第一次使用 fileImporter 选择 pdf 时,它会显示,但当我第二次这样做时,即使 .navigationTitle 发生变化,它也不会改变。当
@EnvironmentObject
改变时我就应该改变。这可能非常简单,但我找不到任何适合这种情况的好的教程。
这是我的 PDF 视图
//
// CustomPDFView.swift
// PDFToSpeach
//
// Created by Dawid Paćkowski on 13/06/2023.
//
import SwiftUI
import PDFKit
struct CustomPDFView: View {
@EnvironmentObject var file: File
var body: some View {
VStack {
NavigationView {
PDFKitView(documentURL: file.url)
.navigationTitle(file.name)
}
}
}
}
struct PDFKitView:UIViewRepresentable{
var documentURL: URL?
func makeUIView(context: Context) -> some UIView {
let pdfView: PDFView = PDFView()
pdfView.document = PDFDocument(url: self.documentURL!)
pdfView.autoScales = true
pdfView.displayDirection = .vertical
return pdfView
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
我像这样改变
@EnvironmentObject
ContentView.swift
.fileImporter(isPresented: $openFile, allowedContentTypes: [UTType.pdf]) { result in
do {
let fileURL = try result.get()
file.url = fileURL
file.name = fileURL.lastPathComponent
} catch {
print(error)
}
}
我认为您需要在调用
PDFView
方法时更新 PDFKitView
中的 updateUIView
,该方法在更新视图时由 SwiftUI 调用
此处已修改
PDFKitView
。另外,我添加了一些改进,例如检查 nil 以免崩溃
struct PDFKitView: UIViewRepresentable {
var documentURL: URL?
func makeUIView(context: Context) -> PDFView {
let pdfView: PDFView = PDFView()
// check if url exists then set a new document
if let documentURL {
pdfView.document = PDFDocument(url: documentURL)
}
pdfView.autoScales = true
pdfView.displayDirection = .vertical
return pdfView
}
func updateUIView(_ uiView: PDFView, context: Context) {
// take the updated document url and apply
// check if url exists then set a new document
if let documentURL {
uiView.document = PDFDocument(url: documentURL)
} else {
uiView.document = nil // clear the document in case if url is nil
}
}
}
它基本上采用新的文档url,用它创建一个新的
PDFDocument
,并将其设置为pdfView(可以使用uiView
中的updateUIView
参数访问(确保在makeUIView
中返回相同的类型) ,在这种情况下它必须返回 PDFView
)),就像在 makeUIView
中一样
还要确保修改您的
File
对象会触发视图更新