在 iOS 中将一个或多个格式化程序与页面渲染器一起使用

发布于 2024-11-05 22:54:11 字数 748 浏览 1 评论 0原文

有没有人尝试过使用多个格式化程序(UIViewPrintFormatterUIMarkupTextPrintFormatterUISimpleTextPrintFormatter)和页面渲染器(UIPrintPageRenderer)进行打印内容?

我试图将两个 UIMarkupTextPrintFormattersUIPrintPageRenderer 子类一起使用,但我无法获得打印。我正在使用 中的 MyPrintPageRenderer 类PrintWebView示例代码。

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

有什么建议吗?

Has anyone tried using multiple formatters (UIViewPrintFormatter, UIMarkupTextPrintFormatter, UISimpleTextPrintFormatter) with a page renderer (UIPrintPageRenderer) to print the content?

I'm trying to use two UIMarkupTextPrintFormatters with a UIPrintPageRenderer subclass, but i'm failing to get the print. I'm using MyPrintPageRenderer class from PrintWebView sample code.

I've gone through the Apple's documentation but it isn't very helpful, and there is no sample code associated with the description. I've tried a couple of solutions but so far I haven't had any success.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

感性不性感 2024-11-12 22:54:11

事实上,“打印”部分的活动非常少,这表明要么没有多少人使用此 API,要么使用此 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 结束的位置继续打印。

The fact that there is very little activity in the "Printing" section suggests that either not many people are using this, or people using this API are not visiting this community, or people are just ignoring the question for some reason.

Anyways, i was able to solve my problem. I was using setPrintFormatters: method earlier which wasn't/isn't working. I don't know why. So, i started experimenting with addPrintFormatter:startingAtPageAtIndex: method instead. And here's how i solved my problem:

// 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];

In the MyPrintPageRenderer, i used following code to update/correct the startPage property so that a new page is used for each formatter:

- (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];
}

I still don't know if there is anyway to APPEND the printable content of both htmlFormatter and listHtmlFormatter (using this approach). e.g. rather than using a new page for listHtmlFormatter, continue printing from where htmlFormatter ended.

勿忘初心 2024-11-12 22:54:11

我在这里添加这个额外信息答案是因为我花了 2 天的时间研究这个和 Mustafa 的答案救了我。希望所有这些都集中在一个地方,可以为其他人节省大量浪费的时间。

我试图弄清楚为什么我无法让自定义的 UIPrintPageRenderer 迭代我需要打印的多个 UIWebViews 中的 viewPrintFormatter 数组在一项工作中,并让它正确计算 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;
});

I'm adding this extra info answer here because I spent 2 days dk'n around with this and Mustafa's answer saved me. Hopefully all this in one place will save others a lot of wasted time.

I was trying to figure out why I was unable get my custom UIPrintPageRenderer to iterate over an array of viewPrintFormatter from several UIWebViews that I need to print in ONE job, and have it properly calculate pageCount as these Apple docs suggest it should: PrintWebView

The key was to add them via this method:

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

and NOT this one:

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

The Apple docs suggest that the UIPrintPageRenderer gets page count from the print formatters in the array as long as the proper metrics are set on the print formatters, as Mustafa shows above. But it only works if you add them via addPrintFormatter:startingAtPageAtIndex:

If you add them as an array, the printFormatters (regardless of what metrics you set on them) will return a page count of 0!

One additional note for people using this approach, put the update to viewPrintFormatter.startPage in a dispatch_async block, else you'll get an exception:

dispatch_async(dispatch_get_main_queue(), ^{
    myFormatter.startPage = startPage;
    startPage = myFormatter.startPage + myFormatter.pageCount;
});
土豪 2024-11-12 22:54:11

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

__block NSUInteger startPage

如果要在dispatch_async块内使用它

To add to @Mustafa's answer,
startPage needs to be declared as:

__block NSUInteger startPage

if it's to be used inside the dispatch_async block

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文