如何一次性打印多个打印格式化程序?

我的最终目标是创build多个UIMarkupTextPrintFormatter并将它们全部打印在一个打印作业中。

例如,第一个格式化程序包含填充第一页和第二页一点点的文本。 虽然仍然有空间可以打印第二个格式化程序,但是我希望第二个格式化程序在第三个页面上打印。 所以基本上,在打印另一个格式化程序之前,请启动一个新页面

我不知道一个格式化程序在编译时会填满多less页,因为它取决于用户input。 也许1,2或更多。

我听说我需要使用UIPrintPageRenderer所以我阅读它的文档,并试着这样做:

 // I'm using webviews here because I don't want to write 2 pages worth of markup... // it should be the same anyway. The two webviews display different wikipedia articles // Also, don't judge my variable names. I'm lazy and this is just test code... let formatter = webView.viewPrintFormatter() let formatter1 = webView2.viewPrintFormatter() formatter.contentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72) formatter1.contentInsets = UIEdgeInsets(top: 72, left: 72, bottom: 72, right: 72) let renderer = UIPrintPageRenderer() renderer.addPrintFormatter(formatter, startingAtPageAt: 0) renderer.addPrintFormatter(formatter1, startingAtPageAt: formatter.pageCount) printController.printPageRenderer = renderer printController.present(animated: true, completionHandler: nil) 

要添加第二个打印格式化程序,我使用formatter.pageCount作为第二个参数。 我希望它会在第一个的最后一页之后添加第二个格式化程序。 但事实并非如此。 它只打印在第二个格式化器的东西。

我打印了formatter.pageCount ,发现它的值是0。

我完全困惑。 我怎样才能得到一个格式化程序将填满多less页?

我也试图实现我自己的渲染器:

 class MyRenderer: UIPrintPageRenderer { override func drawPrintFormatter(_ printFormatter: UIPrintFormatter, forPageAt pageIndex: Int) { printFormatter.draw(in: self.printableRect, forPageAt: pageIndex) } } 

但是当打印交互控制器显示时,它只是崩溃了:

尝试从主线程或Web线程以外的线程获取Weblocking。 这可能是从辅助线程调用UIKit的结果。 现在崩溃…

我在代码中做了什么错误?

根据文档看来,UIPrintFormatter在计算格式中要打印的页面数量之前需要所有的信息。

UIPrintFormatter发布一个界面,允许您指定打印作业的起始页面和打印内容周围的边距; 给定信息和内容,打印格式化程序计算打印作业的页数。

所以这不会发生,除非UIPrintFormatter开始打印内容。

由于UIPrintPageRenderer可能使用UIPrintFormatter,它实际上可以获得与格式化程序相关联的页面数量,并且您只需要覆盖numberOfPages以在每个页面上设置不同的格式化程序。

以下是Apple的示例代码。 哪个完全相同的事情 – 在每个页面上附加多个格式化程序( UIMarkupTextPrintFormatter )。

它在这里覆盖numberOfPages:

 - (NSInteger)numberOfPages { self.printFormatters = nil; [self setupPrintFormatters]; return [super numberOfPages]; } 

并附上格式化程序到这里的每一页:

  /* Iterate through the recipes setting each of their html representations into a UIMarkupTextPrintFormatter and add that formatter to the printing job. */ - (void)setupPrintFormatters { NSInteger page = 0; CGFloat previousFormatterMaxY = CGRectGetMinY(self.contentArea); for (Recipe *recipe in recipes) { NSString *html = recipe.htmlRepresentation; UIMarkupTextPrintFormatter *formatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:html]; [formatterToRecipeMap setObject:recipe forKey:formatter]; // Make room for the recipe info UIEdgeInsets contentInsets = UIEdgeInsetsZero; contentInsets.top = previousFormatterMaxY + self.recipeInfoHeight; if (contentInsets.top > CGRectGetMaxY(self.contentArea)) { // Move to the next page page++; contentInsets.top = CGRectGetMinY(self.contentArea) + self.recipeInfoHeight; } formatter.contentInsets = contentInsets; // Add the formatter to the renderer at the specified page [self addPrintFormatter:formatter startingAtPageAtIndex:page]; page = formatter.startPage + formatter.pageCount - 1; previousFormatterMaxY = CGRectGetMaxY([formatter rectForPageAtIndex:page]); } } 

简而言之,它是根据内容区域,内容插入计算页码,然后通过调用API将格式器附加到页面上:

  [self addPrintFormatter:formatter startingAtPageAtIndex:page]; 

这种方式渲染器有关于每个页面的格式化程序的信息。 你可以在这里find完整的代码

希望它会有所帮助。