如何在 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)
}