UIMarkupTextPrintFormatter PDF creation with custom background and transparent HTML content
Asked Answered
M

2

13

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?

Macropterous answered 3/10, 2017 at 14:15 Comment(1)
I haven't used UIPrintPageRenderer but I have used TCPDF (a similar PDF generator) and TCPDF only supports HTML 4, which -- if I recall correctly -- doesn't support transparency.Chopper
M
1

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

Macropterous answered 3/4, 2018 at 14:22 Comment(0)
J
2

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.

Jumbuck answered 10/10, 2017 at 18:43 Comment(3)
thank you for the answer! I tried solution A and B but they did not work. We have already tried solution C to no avail. Solution D is currently not an option in our project. Regarding solution C: Before we create the pdf we display the html page in a UIWebView and then after is is fully rendered we pass the html string to the UIMarkupTextPrintFormatter and build the pdf. For every page before we render the html page into the pdf we set a background to the whole pdf page. In the web view and also in tests with browsers we can clearly see that the html page is transparent.Macropterous
So you're able to overlay your app content with a web view containing HTML with a transparent background, yes? Does the PDF serve further utility as opposed to just overlaying the HTML used to render the PDF? I ask because it may not be feasible to render a transparent PDF using these libraries. If another solution is possible, it may be worth pursuing that solution.Jumbuck
the pdf serves the purpose that we first draw an image (the background) on it and then we draw the html on it which should be transparent so the underlying already inserted background in the context should be visible through the html. Currently it is not possible/feasible for us to draw/insert the background in the html itself.Macropterous
M
1

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

Macropterous answered 3/4, 2018 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.