IOS Swift共享PDF文档与图像



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

有人知道吗?

我找到了一个解决我的问题的方法:到目前为止,我发现的唯一解决方案是创建一个虚拟的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))
}

最新更新