I’m using WKWebView in an iOS app to render and manipulate some HTML content. At a certain point, I’m generating a PDF from the rendered HTML in the WKWebView. The issue I’m facing involves images that are dynamically loaded into the DOM.
In a regular browser, everything works fine, and when printing, the images avoid breaking across pages if a page break is necessary. However, when generating the PDF in iOS from WKWebView, the images are getting cut off at random heights based on the page size and the image position.
How can I avoid having images break across pages when generating PDFs in iOS from WKWebView?
The template HTML code can be found here.
Any guidance or solutions would be greatly appreciated!
func createPdf(completion: @escaping (PDFDocument?) -> Void) {
let formatter: UIViewPrintFormatter = self.viewPrintFormatter()
let render = UIPrintPageRenderer()
render.addPrintFormatter(formatter, startingAtPageAt: 0)
let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8)
let printableWidth = page.width - 2 * 32
let printableHeight = page.height - 2 * 64
let printable = CGRect(x: 32, y: 32, width: printableWidth, height: printableHeight)
render.setValue(NSValue(cgRect: page), forKey: "paperRect")
render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil)
for i in 0..<render.numberOfPages {
UIGraphicsBeginPDFPage();
let bounds = UIGraphicsGetPDFContextBounds()
render.drawPage(at: i, in: bounds)
if i > 0 {
let pageNumber = i
let footerText = "Page (pageNumber)"
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor.black
]
let textSize = footerText.size(withAttributes: attributes)
let textRect = CGRect(
x: bounds.width - textSize.width - 32,
y: bounds.height - textSize.height - 20,
width: textSize.width,
height: textSize.height
)
footerText.draw(in: textRect, withAttributes: attributes)
}
}
UIGraphicsEndPDFContext()
completion(PDFDocument(data: pdfData as Data))
}
One approach is to increase the WKWebView content size to accommodate larger content. This will help avoid image breaks by ensuring that the entire web content fits within the page boundaries before rendering.
webView.evaluateJavaScript(“document.body.style.zoom = ‘0.8’;”, completionHandler: nil)
By zooming out the content (e.g., 0.8 scale), you ensure that larger images and content sections are less likely to span across multiple pages.
1