SwiftUI 通過 UIViewRepresentable protocol 來封裝 PDFView,查看PDF
Xcode 14.0, swift 5.7, iOS 16.0
2022-09-21
SwiftUI雖然已經提供了很多內建的元件,但SwiftUI還沒有UIKit成熟,所以有些時候需要借助UIKit來實現,要做這個工作,就要通過SwiftUI提供的UIViewRepresentable protocol來與UIKit中的視圖UIView作橋樑溝通,這次試試把PDFView打包成View來在SwiftUI里面使用。
1. 使用UIViewRepresentable protocol,主要要實現兩個方法:創建UIView的makeUIView方法 和 更新UIView的updateUIView方法 。
struct CustomView: UIViewRepresentable {
func makeUIView(context: Context) -> some UIView {
// 返回 UIView object
}
func updateUIView(_ uiView: some UIView, context: Context) {
// 更新 UIView
}
}
2. 在makeUIView方法中初始化一個PDFView,並把pdf檔案內容所代表的data傳給PDFView,當data更新時,使用updateUIView更新PDFView的document,實現如下:
import SwiftUI
import PDFKit
struct SwiftUIPDfView : UIViewRepresentable {
let data : Data
init(_ data : Data) {
self.data = data
}
func makeUIView(context: Context) -> some UIView {
let pdfView = PDFView()
pdfView.document = PDFDocument(data: self.data)
pdfView.autoScales = true
return pdfView
}
func updateUIView(_ pdfView: some UIView, context: Context) {
(pdfView as! PDFView).document = PDFDocument(data: self.data)
}
}
3. 找一個PDF檔案,將其拉入project中:
4. 最後就可以像一些內建的SwiftUI View來使用,把使用Bundle來取得Hello.pdf內容放到data變量中,再將其傳入SwiftUIPDfView中,實現如下:
struct UIViewRepresentableExample: View {
@State var data : Data?
var body: some View {
VStack {
if data != nil {
SwiftUIPDfView(data!)
}
}
.onAppear {
guard let url = Bundle.main.url(forResource: "Hello", withExtension: "pdf") else {
return
}
self.data = try? Data(contentsOf: url)
}
}
}