htmliosprintinguiwebviewpage-break

How do you print page breaks with iOS?


I'm generating a multi-page html document that I'd like to send to an Airprint printer from my app. Each page is discrete and must begin on it's own sheet.

This should be relatively simple - the content of each page is immediately followed by a div element having display: block; page-break-after: always; Here is a simple example:

<html>
  <head>
    <title>Printing with Page Breaks</title>
    <style type="text/css">
      @media screen or print {
        div.pageb { display: block; page-break-after: always; }
      }
    </style>
  </head>

  <body>
        <h1>Page 1</h1>
        <p>Lorem ipsum dolor sit amet...</p>
        <div class="pageb"></div>  <!-- should page break here! -->

        <h1>Page 2</h1>
        <p>Lorem ipsum dolor sit amet...</p>
        <div class="pageb"></div>  <!-- should page break here! -->

        <h1>Page 3</h1>
        <p>Lorem ipsum dolor sit amet...</p>
        <div class="pageb"></div>  <!-- should page break here! -->
  </body>
</html>

This document prints perfectly from Safari and Chrome, which both put all page breaks where they should be. On iOS however, the page breaks aren't inserted.

To print the html I'm using a UIPrintInteractionController to print the contents of a UIWebView by way of UIViewPrintFormatter. Something like this:

UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];

UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
controller.printInfo = printInfo;

UIWebView *webViewPrint = [[UIWebView alloc] init];
[webViewPrint loadHTMLString:printHTML baseUrl:@"/"];

UIViewPrintFormatter *viewFormatter = [webViewPrint viewPrintFormatter];
controller.printFormatter = viewFormatter;
controller.showsPageRange = NO;

[controller presentAnimated:YES completionHandler:completionHandler];

This all seems very standard and I'm left wondering why page breaks print properly on other Webkit browsers but not UIWebView. Any ideas on how to do page breaks on iOS?


Solution

  • I don't have a general solution but I did manage to get page breaks working after some fiddling. Seems like UIWebView is a little finicky with where page-break-before/page-break-after can be applied. Taking a hint from this question I decided to try adding my page break styles to the h1 elements instead of divs and to my surprise the pagebreaks appeared. Here's what it looks like now:

    <style type="text/css">
      @media print {
        .pagebreak-before:first-child { display: block; page-break-before: avoid; }
        .pagebreak-before { display: block; page-break-before: always; }
      }
    </style>
    

    ...

    <body>
      <h1 class="pagebreak-before">Page 1</h1>
      <p>Lorem ipsum dolor sit amet...</p>
    
      <h1 class="pagebreak-before">Page 2</h1>
      <p>Lorem ipsum dolor sit amet...</p>
    
      <h1 class="pagebreak-before">Page 3</h1>
      <p>Lorem ipsum dolor sit amet...</p>
    </body>
    

    I also added a duplicate of the .pagebreak-before selector, now having a :first-child pseudo-element. This is to prevent a blank page at the beginning of the document.