Подтвердить что ты не робот

Почему ячейка нижней таблицы, которая имеет центрированный текст, отключается при отображении в формате 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 в их соответствующих ориентациях.

введите описание изображения здесь

4b9b3361

Ответ 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 для отображения ошибок?

Могут ли высоты строк быть процентами?