如何在 swift 中的共享 sheet IOS 处添加创建 PDF 按钮 5
how to add create pdf button at share sheet IOS in swift 5
我使用 uiwebview 打开 url,然后显示共享 sheet,但是没有创建 pdf 按钮。我想像 safari 一样显示创建 pdf 按钮,并从 url 创建 pdf,然后共享 pdf。怎么做?
或者如何从 url webview/uiview 创建 pdf 然后将 pdf 保存到文件?
这是我的分享sheet
这是 safari 共享 sheet 有创建 pdf 按钮
这是我用来展示分享的代码sheet
let items = [URL(string: "https://www.apple.com")!]
let ac = UIActivityViewController(activityItems: items, applicationActivities: nil)
present(ac, animated: true)
extension WKWebView {
// Call this function when WKWebView finish loading
func exportAsPdfFromWebView() -> String {
let pdfData = createPdfFile(printFormatter: self.viewPrintFormatter())
return self.saveWebViewPdf(data: pdfData)
}
func createPdfFile(printFormatter: UIViewPrintFormatter) -> NSMutableData {
let originalBounds = self.bounds
self.bounds = CGRect(x: originalBounds.origin.x,
y: bounds.origin.y,
width: self.bounds.size.width,
height: self.scrollView.contentSize.height)
let pdfPageFrame = CGRect(x: 0, y: 0, width: self.bounds.size.width,
height: self.scrollView.contentSize.height)
let printPageRenderer = UIPrintPageRenderer()
printPageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
printPageRenderer.setValue(NSValue(cgRect: UIScreen.main.bounds), forKey: "paperRect")
printPageRenderer.setValue(NSValue(cgRect: pdfPageFrame), forKey: "printableRect")
self.bounds = originalBounds
return printPageRenderer.generatePdfData()
}
// Save pdf file in document directory
func saveWebViewPdf(data: NSMutableData) -> String {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let docDirectoryPath = paths[0]
let pdfPath = docDirectoryPath.appendingPathComponent("webViewPdf.pdf")
if data.write(to: pdfPath, atomically: true) {
return pdfPath.path
} else {
return ""
}
}
}
extension UIPrintPageRenderer {
func generatePdfData() -> NSMutableData {
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
}
}
您可以从 url webview/uiview 创建 pdf,然后使用此方法将 pdf 保存到文件
我从其他人那里找到了答案
首先我创建新的classPDF.swift
class func generate(using printFormatter: UIPrintFormatter) -> String {
// assign the print formatter to the print page renderer
let renderer = UIPrintPageRenderer()
renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
// static let ANSI_A = CGSize(width:612,height:792)
// static let ANSI_B = CGSize(width:792,height:1224)
// static let ANSI_C = CGSize(width:1584,height:1224)
// static let ANSI_D = CGSize(width:2448,height:1584)
// static let ANSI_E = CGSize(width:3168,height:2448)
//
// static let ISO216_A0 = CGSize(width:2384,height:3370)
// static let ISO216_A1 = CGSize(width:1684,height:2384)
// static let ISO216_A2 = CGSize(width:1190,height:1684)
// static let ISO216_A3 = CGSize(width:842,height:1190)
// static let ISO216_A4 = CGSize(width:595,height:842)
// static let ISO216_A5 = CGSize(width:420,height:595)
// static let ISO216_A6 = CGSize(width:298,height:420)
// static let ISO216_A7 = CGSize(width:210,height:298)
// static let ISO216_A8 = CGSize(width:148,height:210)
// assign paperRect and printableRect values
let page = CGRect(x: 0, y: 0, width: 1190, height: 842) // A3 landscape
// let page = CGRect(x: 0, y: 0, width: 2384, height: 800) // A4, 72 dpi
renderer.setValue(page, forKey: "paperRect")
renderer.setValue(page, forKey: "printableRect")
// create pdf context and draw each page
let pdfData = NSMutableData()
// UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
UIGraphicsBeginPDFContextToData(pdfData, page, nil)
for i in 0..<renderer.numberOfPages {
UIGraphicsBeginPDFPage()
renderer.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}
UIGraphicsEndPDFContext();
// save data to a pdf file and return
guard nil != (try? pdfData.write(to: outputURL, options: .atomic))
else { fatalError("Error writing PDF data to file.") }
return outputURL.absoluteString
}
private class var outputURL: URL {
guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
else { fatalError("Error getting user's document directory.") }
let url = directory.appendingPathComponent(outputFileName).appendingPathExtension("pdf")
print("open \(url.path)")
return url
}
private class var outputFileName: String {
return "generated-\(Int(Date().timeIntervalSince1970))"
}
并调用函数生成pdf然后使用share sheet分享保存文件
让 uiPDFData = PDF.generate(使用:self.uiWebViewPrintFormatter())
打印(uiPDFData)
DispatchQueue.main.async{
let fileURL = NSURL(fileURLWithPath: (uiPDFData))
// Create the Array which includes the files you want to share
var filesToShare = [Any]()
// Add the path of the file to the Array
filesToShare.append(fileURL)
// Make the activityViewContoller which shows the share-view
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
// Show the share-view
if UIDevice.current.userInterfaceIdiom == .pad {
if let popup = activityViewController.popoverPresentationController {
popup.sourceView = self.view
popup.sourceRect = CGRect(x: self.view.frame.size.width / 2, y: self.view.frame.size.height / 4, width: 0, height: 0)
}
}
self.present(activityViewController, animated: true, completion: nil)
}
我使用 uiwebview 打开 url,然后显示共享 sheet,但是没有创建 pdf 按钮。我想像 safari 一样显示创建 pdf 按钮,并从 url 创建 pdf,然后共享 pdf。怎么做?
或者如何从 url webview/uiview 创建 pdf 然后将 pdf 保存到文件?
这是我的分享sheet
这是 safari 共享 sheet 有创建 pdf 按钮
这是我用来展示分享的代码sheet
let items = [URL(string: "https://www.apple.com")!]
let ac = UIActivityViewController(activityItems: items, applicationActivities: nil)
present(ac, animated: true)
extension WKWebView {
// Call this function when WKWebView finish loading
func exportAsPdfFromWebView() -> String {
let pdfData = createPdfFile(printFormatter: self.viewPrintFormatter())
return self.saveWebViewPdf(data: pdfData)
}
func createPdfFile(printFormatter: UIViewPrintFormatter) -> NSMutableData {
let originalBounds = self.bounds
self.bounds = CGRect(x: originalBounds.origin.x,
y: bounds.origin.y,
width: self.bounds.size.width,
height: self.scrollView.contentSize.height)
let pdfPageFrame = CGRect(x: 0, y: 0, width: self.bounds.size.width,
height: self.scrollView.contentSize.height)
let printPageRenderer = UIPrintPageRenderer()
printPageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
printPageRenderer.setValue(NSValue(cgRect: UIScreen.main.bounds), forKey: "paperRect")
printPageRenderer.setValue(NSValue(cgRect: pdfPageFrame), forKey: "printableRect")
self.bounds = originalBounds
return printPageRenderer.generatePdfData()
}
// Save pdf file in document directory
func saveWebViewPdf(data: NSMutableData) -> String {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let docDirectoryPath = paths[0]
let pdfPath = docDirectoryPath.appendingPathComponent("webViewPdf.pdf")
if data.write(to: pdfPath, atomically: true) {
return pdfPath.path
} else {
return ""
}
}
}
extension UIPrintPageRenderer {
func generatePdfData() -> NSMutableData {
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
}
}
您可以从 url webview/uiview 创建 pdf,然后使用此方法将 pdf 保存到文件
我从其他人那里找到了答案
首先我创建新的classPDF.swift
class func generate(using printFormatter: UIPrintFormatter) -> String {
// assign the print formatter to the print page renderer
let renderer = UIPrintPageRenderer()
renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
// static let ANSI_A = CGSize(width:612,height:792)
// static let ANSI_B = CGSize(width:792,height:1224)
// static let ANSI_C = CGSize(width:1584,height:1224)
// static let ANSI_D = CGSize(width:2448,height:1584)
// static let ANSI_E = CGSize(width:3168,height:2448)
//
// static let ISO216_A0 = CGSize(width:2384,height:3370)
// static let ISO216_A1 = CGSize(width:1684,height:2384)
// static let ISO216_A2 = CGSize(width:1190,height:1684)
// static let ISO216_A3 = CGSize(width:842,height:1190)
// static let ISO216_A4 = CGSize(width:595,height:842)
// static let ISO216_A5 = CGSize(width:420,height:595)
// static let ISO216_A6 = CGSize(width:298,height:420)
// static let ISO216_A7 = CGSize(width:210,height:298)
// static let ISO216_A8 = CGSize(width:148,height:210)
// assign paperRect and printableRect values
let page = CGRect(x: 0, y: 0, width: 1190, height: 842) // A3 landscape
// let page = CGRect(x: 0, y: 0, width: 2384, height: 800) // A4, 72 dpi
renderer.setValue(page, forKey: "paperRect")
renderer.setValue(page, forKey: "printableRect")
// create pdf context and draw each page
let pdfData = NSMutableData()
// UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
UIGraphicsBeginPDFContextToData(pdfData, page, nil)
for i in 0..<renderer.numberOfPages {
UIGraphicsBeginPDFPage()
renderer.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}
UIGraphicsEndPDFContext();
// save data to a pdf file and return
guard nil != (try? pdfData.write(to: outputURL, options: .atomic))
else { fatalError("Error writing PDF data to file.") }
return outputURL.absoluteString
}
private class var outputURL: URL {
guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
else { fatalError("Error getting user's document directory.") }
let url = directory.appendingPathComponent(outputFileName).appendingPathExtension("pdf")
print("open \(url.path)")
return url
}
private class var outputFileName: String {
return "generated-\(Int(Date().timeIntervalSince1970))"
}
并调用函数生成pdf然后使用share sheet分享保存文件
让 uiPDFData = PDF.generate(使用:self.uiWebViewPrintFormatter()) 打印(uiPDFData)
DispatchQueue.main.async{
let fileURL = NSURL(fileURLWithPath: (uiPDFData))
// Create the Array which includes the files you want to share
var filesToShare = [Any]()
// Add the path of the file to the Array
filesToShare.append(fileURL)
// Make the activityViewContoller which shows the share-view
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
// Show the share-view
if UIDevice.current.userInterfaceIdiom == .pad {
if let popup = activityViewController.popoverPresentationController {
popup.sourceView = self.view
popup.sourceRect = CGRect(x: self.view.frame.size.width / 2, y: self.view.frame.size.height / 4, width: 0, height: 0)
}
}
self.present(activityViewController, animated: true, completion: nil)
}