【问题标题】:IOS Swift sharing PDF documents with imagesIOS Swift 与图像共享 PDF 文档
【发布时间】:2016-10-13 13:12:46
【问题描述】:

在 IOS 上使用 Swift 共享简单的 PDF 文档时,我遇到了一种奇怪的行为。基本上,如果我创建它并共享它以进行打印,则不包括它应该包含的图像。如果我首先使用 UIViewController 显示它然后共享它就可以了。我就是不明白为什么!

这是我的代码中有趣的部分:

func getHtml() -> String {
    // Create a HTML document to be printed
    // Save data to file
    let fileName = "noteImage.jpeg"
    let pathToInvoiceHTMLTemplate = Bundle.main.path(forResource: "note", ofType: "html")
    let tmpDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory())
    let fileURL = tmpDirectoryURL.appendingPathComponent(fileName)
    let mergedImages = getMergedImages()
    //let pngImageData = UIImagePNGRepresentation(image)
    let imageData = UIImageJPEGRepresentation(mergedImages, 1.0)   // if you want to save as JPEG
    try? imageData!.write(to: URL(fileURLWithPath: fileURL.path), options: [.atomic])
    var htmlText = "<html><body><b>Problem Retrieving Note Template</b></body></html>"

    do {
        // Load the note HTML template code into a String variable.
        htmlText = try String(contentsOfFile: pathToInvoiceHTMLTemplate!)

        // Replace the variables in HTML.
        htmlText = htmlText.replacingOccurrences(of: "__PROJECT_NAME__", with: projectName!)
        htmlText = htmlText.replacingOccurrences(of: "__NOTE_NAME__", with: note!.name)
        htmlText = htmlText.replacingOccurrences(of: "__NOTE_IMAGE__", with: "file:"+fileURL.path)
    }
    catch {
        print("Unable to open and use HTML template files.")
    }
    return htmlText
}

func getPdf() -> NSMutableData {
    // Create a PDF document from the HTML to be shared
    // Format HTML
    let fmt = UIMarkupTextPrintFormatter(markupText: getHtml())
    // Assign print formatter to UIPrintPageRenderer
    let render = UIPrintPageRenderer()
    render.addPrintFormatter(fmt, startingAtPageAt: 0)
    // Assign paperRect and printableRect
    let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi
    let printable = page.insetBy(dx: 0, dy: 0)
    render.setValue(NSValue(cgRect: page), forKey: "paperRect")
    render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
    // Create PDF context and draw
    let pdfData = NSMutableData()
    UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)
    for i in 1...render.numberOfPages {
        UIGraphicsBeginPDFPage();
        let bounds = UIGraphicsGetPDFContextBounds()
        render.drawPage(at: i - 1, in: bounds)
    }
    UIGraphicsEndPDFContext();
    return pdfData
}

@IBAction func shareNote(_ sender: UIBarButtonItem) {
    // Called in direct sharing
    let firstActivityItem = "Text int the message"
    let docToShare = getPdf()        
    let activityViewController : UIActivityViewController = UIActivityViewController(
        activityItems: [firstActivityItem, docToShare], applicationActivities: nil)

    // This lines is for the popover you need to show in iPad
    activityViewController.popoverPresentationController?.barButtonItem = sender

    // This line remove the arrow of the popover to show in iPad
    activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection()
    activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)

    // Anything you want to exclude
    activityViewController.excludedActivityTypes = [
        UIActivityType.postToWeibo,
        UIActivityType.assignToContact,
        UIActivityType.saveToCameraRoll,
        UIActivityType.addToReadingList,
        UIActivityType.postToFlickr,
        UIActivityType.postToVimeo,
        UIActivityType.postToTencentWeibo,
    ]

    self.present(activityViewController, animated: true, completion: nil)
}

@IBAction func shareDocument(_ sender: UIBarButtonItem) {
    // Called in the preview controller when the HTML is displayed
    let firstActivityItem = "Text in the message"
    let docToShare = getPdf()
    let activityViewController : UIActivityViewController = UIActivityViewController(
        activityItems: [firstActivityItem, docToShare], applicationActivities: nil)

    // This lines is for the popover you need to show in iPad
    activityViewController.popoverPresentationController?.barButtonItem = sender

    // This line remove the arrow of the popover to show in iPad
    activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection()
    activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 150, y: 150, width: 0, height: 0)

    // Anything you want to exclude
    activityViewController.excludedActivityTypes = [
        UIActivityType.postToWeibo,
        UIActivityType.assignToContact,
        UIActivityType.saveToCameraRoll,
        UIActivityType.addToReadingList,
        UIActivityType.postToFlickr,
        UIActivityType.postToVimeo,
        UIActivityType.postToTencentWeibo,
    ]

    self.present(activityViewController, animated: true, completion: nil)        
}

有人知道吗?

【问题讨论】:

    标签: swift pdf-generation


    【解决方案1】:

    我找到了解决问题的方法: 到目前为止,我发现的唯一解决方案是创建一个我隐藏的虚拟 UIWebView。我在 UIWebView 中加载 HTML,然后创建 PDF。这是我的代码:

        override func viewDidLoad() {
        super.viewDidLoad()
    
        hiddenWebView.loadHTMLString(htmlText, baseURL: nil)
        hiddenWebView.isHidden = true
    }
    
    override func viewDidAppear(_ animated: Bool) {
        pdfDocument = getPdf()
        let tmpDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory())
        let fileURL = tmpDirectoryURL.appendingPathComponent("document.pdf")
        pdfDocument.write(to: fileURL, atomically: false)
        documentWebView.loadRequest(URLRequest(url: fileURL))
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多