更新。下面的解决方案在 iOS 上运行良好,但我刚刚注意到 现在 您正在寻找 macOS 解决方案。如果这个解决方案可能有任何帮助,请告诉我......抱歉造成混淆;)
您现在可以为此使用UIView.viewPrintFormatter() 方法(来自UIView 类):
为接收视图返回一个打印格式化程序。
在启动打印作业时,您可以调用此方法为您的视图获取适当的视图打印格式化程序对象。您可以使用格式化程序对象在打印期间为您的视图配置页面布局选项。
例如:
import UIKit
import WebKit
import PDFKit
extension WKWebView {
/// Exports a PDF document with this web view current contents.
/// Only call this function when the web view has **finished** loading.
func exportAsPDF() -> PDFDocument? {
guard self.isLoading == false else {
print("WKWebView still loading!")
return nil
}
let pdfData = createPDFData()
return PDFDocument(data: pdfData)
}
private func createPDFData() -> Data {
let oldBounds = self.bounds
var printBounds = self.bounds
printBounds.size.height = scrollView.contentSize.height
self.bounds = printBounds
var printableRect = printBounds
printableRect.origin = .zero
let printRenderer = UIPrintPageRenderer()
printRenderer.addPrintFormatter(self.viewPrintFormatter(), startingAtPageAt: 0)
printRenderer.setValue(NSValue(cgRect: UIScreen.main.bounds), forKey: "paperRect")
printRenderer.setValue(NSValue(cgRect: printableRect), forKey: "printableRect")
self.bounds = oldBounds
return printRenderer.generatePDFData()
}
}
并将以下辅助方法也添加到UIPrintPageRenderer:
extension UIPrintPageRenderer {
func generatePDFData() -> Data {
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, self.paperRect, nil)
self.prepare(forDrawingPages: NSMakeRange(0, self.numberOfPages))
let printRect = UIGraphicsGetPDFContextBounds()
for pdfPage in 0..<self.numberOfPages {
UIGraphicsBeginPDFPage()
self.drawPage(at: pdfPage, in: printRect)
}
UIGraphicsEndPDFContext()
return pdfData as Data
}
}
最后,您现在可以使用上面定义的exportAsPDF() API 保存 PDF:
let webView: WKWebView = ...
let pdfDocument = webView.exportAsPDF()!
let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let pdfFile = docsDir.appendingPathComponent("WebViewPDF.pdf")
try! pdfDocument.write(to: pdfFile)