ios - 从特定视图创建 PDF 文件
问题描述
我想从视图 X 创建一个 PDF 文件。从 Alex 的问题中报告和提取的代码有效,但只创建了主视图的 PDF(视图 A)。我如何告诉他创建 View X 的 PDF?
// From Main View A
func savePdf() {
let view = ViewX() // <--- This is the View I would like to transform, not linked to View A
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let outputFileURL = documentDirectory.appendingPathComponent("ViewX.pdf")
let dpiScale: CGFloat = 4
// for A5 page size inches * 72
let pageSize = CGSize(width: 5.8 * 72, height: 8.3 * 72)
let pdfVC = UIHostingController(rootView: view)
pdfVC.view.frame = CGRect(origin: .zero, size: pageSize * dpiScale)
let rootVC = UIApplication.shared.windows.first?.rootViewController
rootVC?.addChild(pdfVC)
rootVC?.view.insertSubview(pdfVC.view, at: 0)
let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(origin: .zero, size: pageSize))
DispatchQueue.main.async {
do {
try pdfRenderer.writePDF(to: outputFileURL, withActions: { (context) in
context.beginPage()
rootVC?.view.layer.render(in: context.cgContext)
self.pdfURL = outputFileURL
})
} catch {
print("error.localizedDescription")
}
}
pdfVC.removeFromParent()
pdfVC.view.removeFromSuperview()
}
解决方案
我有同样的问题。这对我有用:
import SwiftUI
func exportToPDF() {
let outputFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("SwiftUI.pdf")
let pageSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
//View to render on PDF
let myUIHostingController = UIHostingController(rootView: ContentView())
myUIHostingController.view.frame = CGRect(origin: .zero, size: pageSize)
//Render the view behind all other views
guard let rootVC = UIApplication.shared.windows.first?.rootViewController else {
print("ERROR: Could not find root ViewController.")
return
}
rootVC.addChild(myUIHostingController)
//at: 0 -> draws behind all other views
//at: UIApplication.shared.windows.count -> draw in front
rootVC.view.insertSubview(myUIHostingController.view, at: 0)
//Render the PDF
let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(origin: .zero, size: pageSize))
DispatchQueue.main.async {
do {
try pdfRenderer.writePDF(to: outputFileURL, withActions: { (context) in
context.beginPage()
myUIHostingController.view.layer.render(in: context.cgContext)
})
print("wrote file to: \(outputFileURL.path)")
} catch {
print("Could not create PDF file: \(error.localizedDescription)")
}
//Remove rendered view
myUIHostingController.removeFromParent()
myUIHostingController.view.removeFromSuperview()
}
}
注意:当您尝试导出同一个视图时,不要尝试在带有 .onAppear 的视图中使用此功能。这自然会导致无限循环。
我希望这有帮助!
推荐阅读
- excel - 限制线 枢轴区域图
- jquery - 从某些元素的标题和第一个子元素中删除 href
- mysql - 使用基于另一个已填充表的 INNER JOIN UPDATE 语句更新空表
- flutter - Flutter http 维护 PHP 会话
- python - 如何从 Python 中的 DataFrame 列中删除选定的特殊字符
- linux - 具有多个 Web 服务器和共享文件的横向扩展方案
- c# - 从一个对象中的 2 个表中获取行
- javascript - 从其他函数 javascript 访问变量
- r - R - NA 时将行折叠到最接近的日期
- fortran - 您如何阅读 Fortran 中文件的最后两行以外的所有内容?