2016-10-25 19 views
5

イムをレンダリングすることはありません:UIMarkupTextPrintFormatterは、SWIFT 3.0のHTMLコンテンツのうち、PDFファイルを作成するbase64で画像に

/** 
* 
*/ 
func exportHtmlContentToPDF(HTMLContent: String, filePath: String) { 
    // let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: 694, height: 603)); 

    // webView.loadHTMLString(HTMLContent, baseURL: nil); 

    let pdfPrinter = PDFPrinter(); 
    let printFormatter = UIMarkupTextPrintFormatter(markupText: HTMLContent); 
    // let printFormatter = webView.viewPrintFormatter(); 

    pdfPrinter.addPrintFormatter(printFormatter, startingAtPageAt: 0); 

    let pdfData = self.drawPDFUsingPrintPageRenderer(printPageRenderer: pdfPrinter); 

    pdfData?.write(toFile: filePath, atomically: true); 
} 

/** 
* 
*/ 
func drawPDFUsingPrintPageRenderer(printPageRenderer: UIPrintPageRenderer) -> NSData! { 
    let data = NSMutableData(); 

    UIGraphicsBeginPDFContextToData(data, CGRect.zero, nil); 

    printPageRenderer.prepare(forDrawingPages: NSMakeRange(0, printPageRenderer.numberOfPages)); 

    let bounds = UIGraphicsGetPDFContextBounds(); 

    for i in 0...(printPageRenderer.numberOfPages - 1) { 
     UIGraphicsBeginPDFPage(); 

     printPageRenderer.drawPage(at: i, in: bounds); 
    } 

    UIGraphicsEndPDFContext(); 

    return data; 
} 

すべては私のbase64でエンコードされた画像を除いて微細化されます。ウェブビューまたはSafariまたはChromeブラウザのHTMLコンテンツ自体が正しく表示され、すべての画像が正しく表示されます。しかし、画像は決してpdfにレンダリングされません。

なぜ画像がレンダリングされず、レンダリングされるのですか?

+0

私は実験を行うことをお勧めします。 2つの画像を保持するクレタHTML。 Fistはbase64でエンコードされ、2つ目はファイルイメージを指します。 iPhoneのSafariブラウザでこの画像を開きます。それをPDFとしてiBooksにエクスポートします。両方の画像がネイティブのSafariアプリでレンダリングされていることを確認してください。 – Ramis

+0

iOSプラットフォーム向けにやっていますか? – Ramis

+0

私はiOSプラットフォームでそれをします。画像ファイルでテストしますが、btwでテストします。自分のhtmlテンプレートを含むwebviewを開くと、base64イメージが正しく表示されます。 – Mulgard

答えて

3

これは、WebKitが最初にHTMLを解析して複数のイベントループサイクルでコンテンツをレンダリングするためです。したがって、ページのDOMだけでなく、リソースの読み込みが完了するまで待つ必要があります。また、あなたのコードをリファクタリングして、webviewが最初に読み込まれるようにする必要があります。そして、その内容をエクスポートするだけです。

エクスポートを開始する正しい時刻を判断するには、WebビューでDOMドキュメントの状態を確認します。そこにこれを行うには複数の方法がありますが、私が見つける最も読みやすいオプションがa port of an answer to a related Objective-C questionです:あなたUIWebViewDelegate実装では、document.readyStateを監視するために、次のようにwebViewDidFinishLoadを実装:

func webViewDidFinishLoad(_ webView: UIWebView) { 

     guard let readyState = webView.stringByEvaluatingJavaScript(from: "document.readyState"), 
      readyState == "complete" else 
     { 
      // document not yet parsed, or resources not yet loaded. 
      return 
     } 

     // This is the last webViewDidFinishLoad call --> export. 
     // 
     // There is a problem with this method if you have JS code loading more content: 
     // in that case -webViewDidFinishLoad can get called again still after document.readyState has already been in state 'complete' once or more. 
     self.exportHtmlContentToPDF(…) 
    } 
+0

これは私の画面を無限に常にちらつきます – RJH

+1

質問がUIMarkupTextPrintFormatterに関するものであれば、なぜWebKitを取りますか? –

1

解決策を見つけました。

PDFへの書き出しは、レンダリング処理が完了する前に行われます。あなたが非常に小さい絵を置くならば、それはPDFに現れています。画像が大きすぎるとレンダリング処理に時間がかかりすぎますが、PDFエクスポートはレンダリングが完了するのを待っていません。

それでは、私はそれを動作させるためにやったことは、次のとおりです。

私はPDFにエクスポートする前に、私はWebViewの中にHTMLの結果を示します。 WebViewはすべてを正しくレンダリングしています.PDFへの書き出しを押すと、内部のすべての画像がPDFに正しく表示されます。

だから、これは巨大な遅れだと思うので、レンダリングプロセスが終了するのをPDF Exporterに指示する方法はありません。

+1

はい、DOMの解析と読み込みは非同期です。幸いなことに、私の答えに概説した文書がエクスポート準備ができている正確なタイミングを判断する簡単な方法があります:http://stackoverflow.com/a/40320983/504931 – mz2

関連する問題