Question
I have an iOS app that takes an html file, turns it into a PDF, and displays it to a WebKit web view. I have a weird problem where the bottom table cell gets cut off when I display to PDF. The weird thing is that the bottom table is only cut off when the text is centered. If it is left-aligned, everything works fine. Why does this happen?
Please note that I am not looking for a work around solution. Rather, I am seeking to understand why this happens. Is this a bug in iOS? Or did I miss something?
Overview
In the image below, there are two tables <table>
. One table is large, has a reddish (coral) background, and has a height of 505px. The other table is below the first with a white background (height is not set). Both have some text. The text is centered for both tables.
The navbar title shows the details of the current view. For example, as shown in the image below, a title of PDF Landscape 505 means that the view shows a PDF in landscape dimensions with a main table height of 505px.
The Problem
The problem arises when I increase the height by 10px. In the image below, the main table height is 515px and the lower table is now cut off.
Take the exact same html and css code and change only the text-alignment to be left-aligned. Now the lower table is not cut off anymore. I also changed the background color to green for distinction. Green means that text is left-aligned. Red means that text is centered.
The following image shows a main-table height of 745px and still the lower table is not cut off because it is left-aligned.
Code
Below is the html code used for this test.
<!DOCTYPE html>
<html>
<head>
<title>#COLOR#</title>
<meta charset="utf-8">
<style>
table, th, td {
border-collapse: collapse;
border: 3px solid black;
text-align: #ALIGN#;
}
table.main-table {
width: 1012px;
height: #HEIGHT#px;
background-color: #COLOR#;
}
table.bottom-table {
width: 1012px;
}
</style>
</head>
<body>
<table class="main-table">
<tr><td>Hello World.</td></tr>
</table>
<table class="bottom-table">
<tr><td>This text gets cut off when centered. It does *not* get cut when left-aligned.</td></tr>
</table>
</body>
</html>
In MyViewController
, the getHTML()
function pulls the html source from sample.html
. The function then replaces #ALIGN#
, #COLOR#
, and #HEIGHT#
with their respective values.
func getHTML() -> String? {
let htmlPath: String? = Bundle.main.path(forResource: htmlResource, ofType: "html")
guard let path = htmlPath else { return nil }
do {
// Load the HTML template code into a String variable.
var html = try String(contentsOfFile: path)
html = html.replacingOccurrences(of: "#HEIGHT#", with: tableHeight.description)
html = html.replacingOccurrences(of: "#COLOR#", with: colorState.rawValue)
html = html.replacingOccurrences(of: "#ALIGN#", with: alignState.rawValue)
return html
} catch {
print("Error: " + error.localizedDescription)
}
return nil
}
The PDFBuilder class handles the PDF creation with one function:
static func exportHTMLToPDF(html: String, frame: CGRect) -> Data {
// Set a printable frame and inset
let pageFrame = frame
let insetRect = pageFrame.insetBy(dx: 10.0, dy: 10.0)
// Create a UIPrintPageRenderer and set the paperRect and printableRect using above values.
let pageRenderer = UIPrintPageRenderer()
pageRenderer.setValue(pageFrame, forKey: "paperRect")
pageRenderer.setValue(insetRect, forKey: "printableRect")
// Create a printFormatter and pass the HTML code as a string.
let printFormatter = UIMarkupTextPrintFormatter(markupText: html)
// Add the printFormatter to the pageRenderer
pageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
// This data var is where the PDF will be stored once created.
let data = NSMutableData()
// This is where the PDF gets drawn.
UIGraphicsBeginPDFContextToData(data, pageFrame, nil)
UIGraphicsBeginPDFPage()
pageRenderer.drawPage(at: 0, in: UIGraphicsGetPDFContextBounds())
print("bounds: " + UIGraphicsGetPDFContextBounds().debugDescription)
UIGraphicsEndPDFContext()
return data as Data
}
This project is also on Github:
https://github.com/starkindustries/PrintPDFTest
Troubleshooting Steps Taken
- Dimensions: I tried playing around with the size of the PDF dimensions. This did not make a difference in the result.
- Columns: I tried using multiple columns instead of just one. Same problem; no difference.
- Tables: I tried using just one table instead of two. With one table and two cells, the bottom cell still gets cut off when text is centered; bottom cell does not get cut when text is left-aligned.
- iPhones: I tried simulating on different iPhone devices (iPhone 6s, iPhone 8, iPad Pro). Same issue.
- Div: If you use a div instead of a second table, the problem is magically fixed. But why does a div work and not a table?
App Notes
The top toolbar has two buttons: green and red. Green makes the text left-aligned. Red makes the text centered.
The bottom toolbar has five buttons: rewind, html, portrait, landscape, and fast forward. The rewind button reduces the main table's height by 10px. Fast forward increases the height by 10px. The html button shows the html view. Portrait and landscape show PDF's in their respective orientations.
question from:
https://stackoverflow.com/questions/47655057/why-does-bottom-table-cell-that-has-centered-text-get-cut-off-when-displayed-as