3

有没有人尝试过使用多个格式化程序(UIViewPrintFormatter, UIMarkupTextPrintFormatter, UISimpleTextPrintFormatter)和页面渲染器(UIPrintPageRenderer)来打印内容?

我正在尝试将两个UIMarkupTextPrintFormattersUIPrintPageRenderer子类一起使用,但我没有得到打印。我正在使用PrintWebView示例代码中MyPrintPageRenderer的类。

我已经浏览了 Apple 的文档,但它不是很有帮助,并且没有与描述相关的示例代码。我已经尝试了几个解决方案,但到目前为止我还没有取得任何成功。

有什么建议么?

4

3 回答 3

6

“打印”部分中几乎没有活动的事实表明,要么没有多少人在使用它,要么使用此 API 的人没有访问这个社区,或者人们只是出于某种原因忽略了这个问题。

无论如何,我能够解决我的问题。我之前使用setPrintFormatters:的方法不起作用/不起作用。我不知道为什么。所以,我开始尝试用addPrintFormatter:startingAtPageAtIndex:方法代替。这就是我解决问题的方法:

// To draw the content of each page, a UIMarkupTextPrintFormatter is used.
NSString *htmlString = [self prepareWebViewHTML];
UIMarkupTextPrintFormatter *htmlFormatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:htmlString];

NSString *listHtmlString = [self prepareWebViewListHTMLWithCSS];
UIMarkupTextPrintFormatter *listHtmlFormatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:listHtmlString];

// I think this should work, but it doesn't! The result is an empty page with just the header and footer text.
// [myRenderer setPrintFormatters:[NSArray arrayWithObjects:htmlFormatter, listHtmlFormatter, nil]];

// Alternatively, i've used addPrintFormatters here, and they just work!
// Note: See MyPrintPageRenderer's numberOfPages method implementation for relavent details.
// The important point to note there is that the startPage property is updated/corrected.
[myRenderer addPrintFormatter:htmlFormatter startingAtPageAtIndex:0];
[myRenderer addPrintFormatter:listHtmlFormatter startingAtPageAtIndex:1];

在 中MyPrintPageRenderer,我使用以下代码更新/更正 startPage 属性,以便为每个格式化程序使用一个新页面:

- (NSInteger)numberOfPages
{
    // TODO: Perform header footer calculations
    // . . .

    NSUInteger startPage = 0;
    for (id f in self.printFormatters) {
        UIPrintFormatter *myFormatter = (UIPrintFormatter *)f;

        // Top inset is only used if we want a different inset for the first page and we don't.
        // The bottom inset is never used by a viewFormatter.
        myFormatter.contentInsets = UIEdgeInsetsMake(0, leftInset, 0, rightInset);

        // Just to be sure, never allow the content to go past our minimum margins for the content area.
        myFormatter.maximumContentWidth = self.paperRect.size.width - 2*MIN_MARGIN;
        myFormatter.maximumContentHeight = self.paperRect.size.height - 2*MIN_MARGIN;

        myFormatter.startPage = startPage;
        startPage = myFormatter.startPage + myFormatter.pageCount;
    }

    // Let the superclass calculate the total number of pages
    return [super numberOfPages];
}

我仍然不知道是否有附加 htmlFormatter 和 listHtmlFormatter 的可打印内容(使用这种方法)。例如,不要为 listHtmlFormatter 使用新页面,而是从 htmlFormatter 结束的地方继续打印。

于 2011-05-10T08:06:41.067 回答
2

我在这里添加了这个额外的信息答案,因为我花了 2 天时间来解决这个问题,而穆斯塔法的回答救了我。希望所有这些都集中在一个地方可以为其他人节省大量浪费的时间。

我试图弄清楚为什么我无法让我的自定义UIPrintPageRenderer遍历我需要在一个作业中打印的viewPrintFormatter几个数组UIWebViews,并让它正确计算 pageCount,因为这些 Apple 文档建议它应该:PrintWebView

关键是通过这种方法添加它们:

-(void)addPrintFormatter:(UIPrintFormatter *)formatter startingAtPageAtIndex:(NSInteger)pageIndex

不是这个:

@property(nonatomic, copy) NSArray <UIPrintFormatter *> *printFormatters

Apple 文档建议UIPrintPageRenderer从数组中的打印格式化程序获取页数,只要在打印格式化程序上设置了正确的指标,如 Mustafa 上面所示。只有通过添加它们才有效addPrintFormatter:startingAtPageAtIndex:

如果将它们添加为数组,则 printFormatters(无论您在它们上设置什么指标)将返回页数 0!

对于使用这种方法的人的一个额外说明viewPrintFormatter.startPage,将更新放在一个dispatch_async块中,否则你会得到一个异常:

dispatch_async(dispatch_get_main_queue(), ^{
    myFormatter.startPage = startPage;
    startPage = myFormatter.startPage + myFormatter.pageCount;
});
于 2016-03-02T21:47:48.223 回答
0

要添加到@Mustafa 的答案, startPage需要声明为:

__block NSUInteger startPage

如果要在 dispatch_async 块内使用

于 2017-10-13T23:57:05.780 回答