IOS Swift 分享带有图片的PDF文档 [英] IOS Swift sharing PDF documents with images

查看:107
本文介绍了IOS Swift 分享带有图片的PDF文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm getting a weird behaviour when sharing a simple PDF document using Swift on IOS. Basicaly if I create it and share it to be printed the image it should contain is not included. If I first display it using a UIViewController and then share it it's fine. I just don't get why !

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

Here are the interresting parts of my code :

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)        
}

有人知道吗?

推荐答案

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

I found a workaround to my problem : The only solution I found so far is to create a dummy UIWebView that I hide. I load the HTML in the UIWebView and then create the PDF. Here is my code :

    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))
}

这篇关于IOS Swift 分享带有图片的PDF文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆