Почему ячейка нижней таблицы, которая имеет центрированный текст, отключается при отображении в формате PDF в iOS?
Вопрос
У меня есть приложение 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 в их соответствующих ориентациях.
![введите описание изображения здесь]()
Ответы
Ответ 1
Я думаю, что это проблема:
table, th, td {
border-collapse: collapse;
border: 3px solid black;
text-align: #ALIGN#;
}
Правило установки в table
, а th, td
выглядит как проблема для меня (имея проблемы с несколькими проблемами, связанными с PDF-документацией)
Если это не text-align
, в соответствии с комментарием DeadLock... тогда это может быть border-collapse
, который применяется к td
(Я думаю, что это просто нужно пойти на стол).
Другой внешний отладчик для такого рода вещей:
* {border:1px solid #f00}
или * {box-shadow: inset 0 0 1px #f00}
(последнее не добавляет ничего к пропорциям элементов, но может не отображаться в виде pdf) эти правила помогут вам сразу увидеть, что делает каждое ваше редактирование к макету, вместо того, чтобы обращаться к инспектору элементов.
Кроме того, убедитесь, что у вас есть хорошее представление о том, как элемент таблицы отображается по умолчанию в этом dom.
При объявлении правил для element
и element.class
вы можете что-то выбросить. Сравните с поведением без стилей, затем добавьте их обратно один за другим.
Я сделал попытку переписать код:
<!DOCTYPE html>
<html>
<head>
<title>COLOR</title>
<meta charset="utf-8">
<style>
table{
border-collapse: collapse;
}
th{
}
td {
border-width:3px;
border-style:solid;
border-color:#000000;
}
tr{
text-align: center;
}
table.main-table {
width: 1012px;
height: 515px; /* There a lot you can do here instead of height: 515px; if needed I can elaborate. I'm guessing the content is varible-height? does flex-box make it through the pdf-generator? */
background-color: #ccc;
}
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>
Другие вопросы:
Можете ли вы проверить его в эмуляции с помощью отладчика?
Или вы можете изменить способ вывода pdf для отображения ошибок?
Могут ли высоты строк быть процентами?