Вопрос
У меня есть приложение iOS, которое принимает html файл, превращает его в PDF файл и отображает его на веб-представление WebKit. У меня есть странная проблема, когда ячейка нижней таблицы отключается, когда я показываю PDF. Странно то, что нижняя таблица обрезается только при центрировании текста. Если он выровнен по левому краю, все работает нормально. Почему это происходит?
Обратите внимание, что я не ищу решения для работы. Скорее, я пытаюсь понять, почему это происходит. Это ошибка в iOS? Или я что-то пропустил?
Обзор
На изображении ниже представлены две таблицы <table>
. Один стол большой, имеет красноватый (коралловый) фон и имеет высоту 505 пикселей. Другая таблица ниже первой с белым фоном (высота не установлена). Оба имеют некоторый текст. Текст центрирован для обеих таблиц.
В заголовке навигатора отображаются сведения о текущем представлении. Например, как показано на рисунке ниже, заголовок PDF Landscape 505 означает, что в представлении показан PDF файл в альбомных размерах с максимальной высотой стола 505 пикселей.
Проблема
Проблема возникает, когда я увеличиваю высоту на 10 пикселей. На изображении ниже высота основного стола составляет 515 пикселей, а нижняя таблица теперь отключена.
Возьмите тот же код html и css и измените выравнивание текста на выравнивание по левому краю. Теперь нижняя таблица больше не отрезана. Я также изменил цвет фона на зеленый для отличия. Зеленый означает, что текст выровнен по левому краю. Красный означает, что текст центрирован.
На следующем рисунке показана высота основного стола 745 пикселей, а нижняя таблица не обрезается, потому что она выравнивается по левому краю.
код
Ниже приведен код html, используемый для этого теста.
<!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>
В MyViewController
функция getHTML()
вытаскивает источник html из sample.html
. Затем функция заменяет #ALIGN#
, #COLOR#
и #HEIGHT#
своими соответствующими значениями.
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
}
Класс PDFBuilder обрабатывает создание PDF с помощью одной функции:
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
}
Этот проект также находится на Github: https://github.com/starkindustries/PrintPDFTest
Действия по устранению неполадок
- Размеры: Я пытался играть с размером размеров PDF. Это не повлияло на результат.
- Столбцы: я попытался использовать несколько столбцов вместо одного. Та же проблема; нет разницы.
- Таблицы: Я попытался использовать только одну таблицу вместо двух. С одной таблицей и двумя ячейками нижняя ячейка по-прежнему отключается, когда текст центрирован; нижняя ячейка не вырезается, когда текст выравнивается по левому краю.
- iPhones: Я пробовал имитировать на разных устройствах iPhone (iPhone 6, iPhone 8, iPad Pro). Такая же проблема.
- Div: Если вы используете div вместо второй таблицы, проблема будет магически исправлена. Но почему работает div, а не таблица?
Заметки о приложении
Верхняя панель инструментов состоит из двух кнопок: зеленый и красный. Зеленый цвет выравнивает текст влево. Красный цвет выравнивает текст.
Нижняя панель инструментов состоит из пяти кнопок: перемотка назад, html, портрет, альбом и ускоренная перемотка вперед. Кнопка перемотка уменьшает высоту основной таблицы на 10 пикселей. Быстрая перемотка вперед увеличивает высоту на 10 пикселей. Кнопка html отображает представление html. Портрет и пейзаж показывают PDF в их соответствующих ориентациях.