Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIMarkupTextPrintFormatter PDF creation with custom background and transparent HTML content

I am using a UIPrintPageRenderer together with a UIMarkupTextPrintFormatter to print an html page which is rendered in a UIWebView. I am trying to achieve the following: I want to render the html content as a transparent layer onto the context but the background color of the html content is always white when rendered with the UIPrintPageRenderer in the context covering up all the content below.

The html style contains the following code snippet:

body {
      background-color: transparent !important;;
      -webkit-print-color-adjust: exact;
}

In the UIWebView I can see that the background of the html is indeed transparent because I set the background of the UIWebView to a different color.

This is the code I use for creating the PDF data:

let printPageRenderer = UIPrintPageRenderer()
let printFormatter = UIMarkupTextPrintFormatter(markupText: htmlContent)
printPageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)

let data = NSMutableData()
UIGraphicsBeginPDFContextToData(data, Constants.Pdf.rect, nil)
let context = UIGraphicsGetCurrentContext()!

for i in 0..<printPageRenderer.numberOfPages {
    UIGraphicsBeginPDFPage()

    let backCoverView = UIView(frame: Constants.Pdf.rect)
    backCoverView.backgroundColor = UIColor(patternImage: UIImage(named: "background.png")!)
    backCoverView.layer.render(in: context)

    context.clear(printableRect)

    printPageRenderer.setValue(NSValue(cgRect: printableRect), forKey: "printableRect")
    printPageRenderer.drawPage(at: i, in: UIGraphicsGetPDFContextBounds())
}

UIGraphicsEndPDFContext()

My problem is that the html content which is rendered over the "background.png" is not transparent but has a white background. The transparent attribute in the html style seems to be ignored by the UIPrintPageRenderer. Setting the background-color in the html style to e.g. blue changes the rendered html background color from white to blue. I also tried making the rendered html transparent by making the context transparent with context.clear(printableRect) to no avail.

How can I make UIPrintPageRenderer print the html content with a transparent background so the already rendered background in the context is not covered by a white background of the html?

like image 913
christopher.online Avatar asked Oct 03 '17 14:10

christopher.online


2 Answers

Solved the problem by switching to a different UIPrintFormatter. Switched from UIMarkupTextPrintFormatter to UIViewPrintFormatter which honoured the transparency.

like image 113
christopher.online Avatar answered Nov 05 '22 00:11

christopher.online


This isn't a guarantee, but as Yvonne mentioned, it's possible that your PDF renderer just doesn't support transparent as a color value.

Possible Solution A

Try creating a 1px by 1px PNG image with just one 100% transparent pixel, then set that as a repeating background image on your element.

Possible Solution B

It's possible that the HTML element itself is white when this library renders it. You can apply CSS to the html tag the same way you did with body.

Possible Solution C

If I understand your case correctly, you're trying to overlay a rendered PDF which is inside of a UIWebView on top of other in-app content. I can't speak to whether a PDF can really support transparency. The UIWebView may have its own properties required (not to mention there may be a PDF viewer with a default background of white in play). If you have control of the UIWebView's styles, take a look at this: How to make a transparent UIWebView

Possible Solution D

Maybe it would be better to use a Canvas (either HTML or Switft) to render an image instead of a PDF. If this works for your use case, it may be a much better option long-term.

like image 24
Dom Ramirez Avatar answered Nov 05 '22 01:11

Dom Ramirez