在 iOS 上将 SwiftUI 视图转换为 PDF

Sn0*_*eze 16 pdf uikit ios swiftui

我正在用 SwiftUI 绘制一些漂亮的图形,因为它非常简单易行。然后我想将整个 SwiftUI 视图导出为 PDF,以便其他人可以以一种很好的方式查看图形。SwiftUI 没有直接为此提供解决方案。

干杯,
亚历克斯

Sn0*_*eze 16

经过一番思考,我想到了将 UIKit 转 PDF 方法和 SwiftUI 结合起来的想法。

首先创建 SwiftUI 视图,然后放入 UIHostingController。您在所有其他视图后面的窗口上渲染 HostingController 并在 PDF 上绘制其图层。下面列出了示例代码。

func exportToPDF() {

    let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let outputFileURL = documentDirectory.appendingPathComponent("SwiftUI.pdf")

    //Normal with
    let width: CGFloat = 8.5 * 72.0
    //Estimate the height of your view
    let height: CGFloat = 1000
    let charts = ChartsView()

    let pdfVC = UIHostingController(rootView: charts)
    pdfVC.view.frame = CGRect(x: 0, y: 0, width: width, height: height)

    //Render the view behind all other views
    let rootVC = UIApplication.shared.windows.first?.rootViewController
    rootVC?.addChild(pdfVC)
    rootVC?.view.insertSubview(pdfVC.view, at: 0)

    //Render the PDF
    let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 8.5 * 72.0, height: height))

    do {
        try pdfRenderer.writePDF(to: outputFileURL, withActions: { (context) in
            context.beginPage()
            pdfVC.view.layer.render(in: context.cgContext)
        })

        self.exportURL = outputFileURL
        self.showExportSheet = true

    }catch {
        self.showError = true
        print("Could not create PDF file: \(error)")
    }

    pdfVC.removeFromParent()
    pdfVC.view.removeFromSuperview()
}
Run Code Online (Sandbox Code Playgroud)


Moz*_*ler 8

我喜欢这个答案,但无法让它发挥作用。我遇到了一个异常并且没有执行捕获。

经过一番摸索,并写了一个 SO Question 询问如何调试它(我从未提交过),我意识到解决方案虽然不明显,但很简单:将渲染阶段包装在对主队列的异步调用中:

//Render the PDF

 let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 8.5 * 72.0, height: height))
 DispatchQueue.main.async {
     do {
         try pdfRenderer.writePDF(to: outputFileURL, withActions: { (context) in
             context.beginPage()
             pdfVC.view.layer.render(in: context.cgContext)
         })
         print("wrote file to: \(outputFileURL.path)")
     } catch {
         print("Could not create PDF file: \(error.localizedDescription)")
     }
 }
Run Code Online (Sandbox Code Playgroud)

谢谢,SnOwfreeze!