html – UIMarkupTextPrintFormatter永远不会渲染base64图像

我在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(…)
    }

相关文章

vue阻止冒泡事件 阻止点击事件的执行 <div @click=&a...
尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用...
后台我拿的数据是这样的格式: [ {id:1 , parentId: 0, name:...
JAVA下载文件防重复点击,防止多次下载请求,Cookie方式快速简...
Mip是什么意思以及作用有哪些