如何一次性打印多个打印格式化程序?
我的最终目标是创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完整的代码
希望它会有所帮助。