The Util Designer
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)
        }
    }
}