本文介绍了如何一次性AirPrint多个打印格式化程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My ultimate goal is to create multiple UIMarkupTextPrintFormatter and print them all in one print job.

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

For example, the first formatter contains text that fills up the first page and a little bit of the second page. Although there is still space left to print the second formatter, I want the second formatter to print on the third page. So basically, before printing another formatter, start a new page.

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

I cannot know how many pages one formatter will fill up at compile time because it depends on user input. Maybe 1, 2 or more.

我听说我需要使用 UIPrintPageRenderer 所以我读了它的文档并尝试过这个:

I heard that I need to use UIPrintPageRenderer so I read its docs and tried this:

// 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 作为第二个参数。我希望它会在第一页的最后一页之后添加第二个格式化程序。但事实并非如此。它只打印第二个格式化程序中的内容。

To add the second print formatter, I used formatter.pageCount as the second argument. I hoped it will add the second formatter after the last page of the first. But it didn't. It only printed the stuff in the second formatter.

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

I printed formatter.pageCount and found its value is 0.

我完全糊涂了。如何获取格式化程序将填充的页数?

I am totally confused. How can I get how many pages a formatter will fill up?

我还尝试实现自己的渲染器:

I also tried to implement my own renderer:

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

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

But then it just crashes when the print interaction controller showed:

我的代码中出错了什么?

What did I do wrong in my code?

推荐答案

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

As per doc it seems, UIPrintFormatter need all the information before it calculates number of pages to print in the format.

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

So this will not happen unless UIPrintFormatter start printing the content.

由于 UIPrintPageRenderer 可以使用 UIPrintFormatter ,它实际上可以获得与格式化程序相关的页数以及所有你需要做的事情是覆盖numberOfPages以在每个页面设置不同的格式化程序。

Since UIPrintPageRenderer may use UIPrintFormatter it can actually get number of pages associated with formatter and all you have to do is to override numberOfPages to setup different formatter at each page.

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

Below is the sample code from Apple. Which does exactly same thing - attaching multiple formatter (UIMarkupTextPrintFormatter) at each pages.

它会覆盖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将格式化程序附加到页面:

In short it is calculating page number based on content area, content inset and then attaching formatter to the page by calling the API:

 [self addPrintFormatter:formatter startingAtPageAtIndex:page];

这样Renderer就每个页面都有关于格式化程序的信息。
你可以找到完整的代码

This way Renderer has information about formatter for each pages.You can find complete code here

希望它会有所帮助。

这篇关于如何一次性AirPrint多个打印格式化程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 22:47