我在swift 3.0中用html内容创建一个pdf文件:
/** * */ 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编码图像,一切都很好. Webview或内部safari或chrome浏览器中的HTML内容本身正确显示并正确显示所有图像.但图像永远不会呈现为PDF格式.
为什么图像没有渲染,我怎样才能渲染它们?
解决方法
发生这种情况是因为WebKit首先将HTML解析为DOM,并在多个事件循环周期中呈现内容.因此,您不仅要等待页面DOM准备好,还要等待资源加载完成.正如您所建议的那样,您需要重构代码,以便首先加载webview,然后才导出其内容.
要确定触发导出的正确时间,您可以在Web视图中观察DOM文档的状态.有多种方法可以做到这一点,但我找到的最可读的选项是a port of an answer to a related Objective-C question:在UIWebViewDelegate实现中,按照以下方式实现webViewDidFinishLoad
以监控document.readyState
:
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(…) }