web-dev-qa-db-ja.com

iOSでPDF)と表示されたときに、テキストが中央に配置されている下部のテーブルセルが切り取られるのはなぜですか?

質問

Htmlファイルを取得してPDFに変換し、WebKitWebビューに表示するiOSアプリがあります。 PDFに表示すると、下のテーブルセルが途切れるという奇妙な問題があります。奇妙なことに、下のテーブルはテキストが中央に配置されている場合にのみ切り取られます。左揃えの場合、すべてが正常に機能します。なぜこれが起こるのですか?

私は回避策を探していないことに注意してください。むしろ、なぜこれが起こるのかを理解しようとしています。これはiOSのバグですか?それとも私は何かを逃しましたか?

概要

以下の画像には、2つのテーブル_<table>_があります。 1つのテーブルは大きく、背景は赤みがかっており(珊瑚)、高さは505pxです。もう1つのテーブルは、最初のテーブルの下にあり、背景は白です(高さは設定されていません)。どちらにもテキストがあります。テキストは両方のテーブルの中央に配置されます。

ナビゲーションバーのタイトルには、現在のビューの詳細が表示されます。たとえば、次の画像に示すように、PDF Landscape 505というタイトルは、ビューにPDFメインテーブルの高さが505pxの横向きの寸法。

enter image description here

問題

高さを10px増やすと、問題が発生します。下の画像では、メインテーブルの高さは515pxで、下のテーブルは切り取られています。

enter image description here

まったく同じhtmlコードとcssコードを使用して、テキストの配置のみを左揃えに変更します。これで、下のテーブルが切り取られなくなりました。また、区別するために背景色を緑に変更しました。緑は、テキストが左揃えであることを意味します。赤は、テキストが中央に配置されていることを意味します。

enter image description here

次の画像は、メインテーブルの高さが745pxであることを示していますが、下のテーブルは左揃えになっているため、切り取られていません。

enter image description here

コード

以下は、このテストに使用された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()関数が_sample.html_から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クラスは、1つの関数で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

実行した手順のトラブルシューティング

  1. 寸法:PDF寸法のサイズを試してみましたが、結果に違いはありませんでした。
  2. 列:1つではなく複数の列を使用してみました。同じ問題;変わりはない。
  3. テーブル:2つではなく1つのテーブルを使用してみました。 1つのテーブルと2つのセルがある場合でも、テキストが中央に配置されていると、下のセルが切り取られます。テキストを左揃えにすると、下部のセルは切り取られません。
  4. iPhone:さまざまなiPhoneデバイス(iPhone 6s、iPhone 8、iPad Pro)でシミュレーションしてみました。同じ問題。
  5. Div:2番目のテーブルの代わりにdivを使用すると、問題は魔法のように修正されます。しかし、なぜdivはテーブルではなく機能するのですか?

アプリノート

上部のツールバーには、の2つのボタンがあります。緑はテキストを左揃えにします。赤はテキストを中央に配置します。

enter image description here

下部のツールバーには5つのボタンがあります:巻き戻しhtmlportraitlandscape、およびfast forwardrewindボタンは、メインテーブルの高さを10px減らします。 早送りは高さを10px増やします。 htmlボタンはhtmlビューを表示します。 Portraitおよびlandscapeは、それぞれの方向でPDFを表示します。

enter image description here

39
Zion Perez

PDFレンダリングで、完全に同じアスペクトとサイズを維持するために、HTMLファイルを一度変換すると(主に解像度の変換の問題のため)、多くの問題が発生しました。

私が見つけた最善かつ最も簡単な回避策は、ドキュメントの高さに正確に合うコンテナにコンテンツをカプセル化することです。ソースhtmlファイルを表示する場合は、メディアクエリを使用して、印刷結果にのみcssコードを適用できます。

table, th, td {
  border-collapse: collapse;
  border: 3px solid black;
  text-align: center;
}

table.main-table {
  width: 1012px;
  height: 515px;
  background-color: #f4f4f4;
}

table.bottom-table {
  width: 1012px;
}

@media print {
  .main-container{
    height:1100px;/* adjust the height to fit your PDF document*/
  }
}
<div class="main-container">
  <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>
 </div>
1
Foxlab

質問が投稿されてからしばらく経ちました。しかし、私はこれに興味をそそられ、なぜこれが起こるのかを理解しようとしていました。

また、これを確認するためにさまざまな組み合わせをテストしてみました。しかし、ネイティブiOSコードは役に立たないようです。しかし、autoの高さをbottom-tableに割り当てると、うまくいくように見えました。ただし、明示的な高さの設定は機能しませんでした。

table.bottom-table {
    width: 1012px;
    height: auto;
}

PDFレンダリング中は、PDFのフレームの設定で問題が発生した可能性がありますが、それ以外の場合は、PortraitとPortraitの両方で問題が解決しないこともご存知だと思います。高さが特定の制限を超えたときのランドスケープモード。

0
D V