iosprintinguiwebviewuiprintpagerenderer

Using One or More Formatters with a Page Renderer in iOS


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?


Solution

  • 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.