【问题标题】:Printing Contents of Multiple UIWebViews in one go一次性打印多个 UIWebView 的内容
【发布时间】:2011-02-20 23:27:33
【问题描述】:

我有一个 iPad 应用程序,它使用 WebViews 来显示 URL 列表。我希望能够一次打印所有 WebView,而无需使用 PrintInteractionController 多次提示用户。问题是 PrintInteractionController 似乎没有这样做的能力。您不能分配多个 viewFormatter,并且 WebViews 不会被识别为 printItems。我也找不到只打印项目而不显示 PrintInteractionController 的方法。

有谁知道这样做的方法吗?

干杯。

【问题讨论】:

    标签: printing uiwebview uiprintinteractioncntrler uiprintpagerenderer uiprintformatter


    【解决方案1】:

    这是一个老问题,但我花了几天时间寻找答案并关注 Apple 文档和示例代码中的一些误导性 cmets。所以,我把它贴在这里是为了节省我浪费的时间。

    具体的问题是:如何编写一个UIPrintPageRenderer,在一个打印作业中打印多个UIWebViews,并提供给 UIPrintInteractionController?

    使用此 Apple 示例代码:PrintWebView,您可以在不涉及首先将所有内容转换为 PDF 的解决方案中取得进展。此文档也将有所帮助:UIPrintPageRenderer。问题是示例应用程序和UPPrintPageRenderer 的文档建议如果您通过此属性添加多个UIPrintFormatter

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

    Apple 为在 PrintWebView 中覆盖 -(NSInteger)numberOfPages 的方法提供的示例代码将正常工作并计算出正确的页数.... 不!

    您需要做的是通过下面显示的方法以非显而易见的方式添加printFormatters,然后更正它们各自的 startPage 属性并共同使用这些属性来计算出正确的 pageCount 以供 UIPrintPageRenderer 返回。相反,使用这个:

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

    为什么这个有效而另一个无效?不知道,可能是一个错误.... 我应该提交 radar :) 但是感谢 @Mustafa 和其他 Stackoverflow answer for the hint

    以下是在一个打印作业中打印多个 UIWebView 的步骤:

    1. 按照上面引用的 PrintWebView 示例中的 Apple 大纲,编写您的 UIPrintPageRenderer 以在 webView.viewPrintFormatters 上设置所需的属性你给它。
    2. 通过以下方式添加 printFormatters:[addPrintFormatter:startingAtPageAtIndex:]
    3. 在您的 UIPrintPageRenderer -(NSInteger)numberOfPages 方法中,从每个格式化程序获取 pageCount,并使用它来更新 startPage 和总页数值。

    这是要遵循的基本代码大纲(仅供参考:此解决方案适用于以 iOS 9.0 的部署目标构建的应用):

    像这样定义你的 UIPrintPageRenderer 类(你并不真的需要 init 方法,但在我的用例中,我在那里设置值,我总是希望这样):

    @interface MyPrintPageRenderer : UIPrintPageRenderer
    @end
    
    @implementation MyPrintPageRenderer
    -(id)init
    {
        self = [super init];
        if(self) {
            self.headerHeight = 0;
            self.footerHeight = 0;
        }
        return self;
    }
    
    // 
    // Set whatever header, footer and insets you want. It is
    // important to set these values to something, so that the print
    // formatters can figure out their own pageCounts for whatever
    // they contain. Look at the Apple sample App for PrintWebView for
    // for more details about these values.
    //
    -(NSInteger)numberOfPages
    {
        __block NSUInteger startPage = 0;
        for(UIPrintFormatter *pf in self.printFormatters) {
            pf.contentInsets = UIEdgeInsetsZero;
            pf.maximumContentWidth = self.printableRect.size.width;
            pf.maximumContentHeight = self.printableRect.size.height;
    
            dispatch_async(dispatch_get_main_queue(), ^{
                pf.startPage = startPage;
                startPage = pf.startPage + pf.pageCount;
            });
        }
        return [super numberOfPages];
    }
    @end
    

    在处理要打印的 UIWebView 的打印操作的 Controller 中,执行以下操作:

    -(void)printWebViews
    {
        MyPrintPageRenderer *pr = [MyPrintPageRenderer new];
        //
        // Add the printFormatters at sequential startingPageIndexes,
        // your renderer will set them to the correct values later based
        // on the various page metrics and their content.
        //
        [pr addPrintFormatter:_webView1.viewPrintFormatter startingAtPageAtIndex:0];
        [pr addPrintFormatter:_webView2.viewPrintFormatter startingAtPageAtIndex:1];      
        [pr addPrintFormatter:_webView3.viewPrintFormatter startingAtPageAtIndex:2];
    
        // Set whatever values needed for these as per Apple docs
        UIPrintInfo *pi = [UIPrintInfo printInfo];
        pi.outputType = UIPrintInfoOutputGeneral;
    
        UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
        pic.printInfo = pi;
        pic.printPageRenderer = pr;
        [pic presentAnimated:NO completionHandler:nil];
    }
    

    瞧!现在......它正常工作 ;)

    【讨论】:

    • 对我来说,这只能通过注释掉dispatch_async 部分并返回startPage 来实现,否则某些页面将无法打印(例如,添加 2 UIPrintFormatter 时仅显示 2 页,而不是3 页)
    【解决方案2】:

    使用 UIPrintIterationController 对象的 printPageRenderer 属性。您可以在一个 UIPrintPageRenderer 子类对象中设置多个 UIPrintFormatter 子类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多