54

I am trying to draw contents of scrollview into a PDF context & I am facing problem with pagination.

Following Code I have used:

- (void)renderTheView:(UIView *)view inPDFContext:(CGContextRef)pdfContext
{
    // Creating frame.
    CGFloat heightOfPdf = [[[self attributes] objectForKey:SRCPdfHeight] floatValue];
    CGFloat widthOfPdf  = [[[self attributes] objectForKey:SRCPdfWidth] floatValue];
    CGRect pdfFrame = CGRectMake(0, 0, widthOfPdf, heightOfPdf);   
    CGRect viewFrame = [view frame];

    if ([view isKindOfClass:[UIScrollView class]])
    {
        viewFrame.size.height = ((UIScrollView *)view).contentSize.height;
        [view setFrame:viewFrame];
    }
    // Calculates number of pages.
    NSUInteger totalNumberOfPages = ceil(viewFrame.size.height/heightOfPdf);

    // Start rendering.
    for (NSUInteger pageNumber = 0; pageNumber<totalNumberOfPages; pageNumber++)
    {
       // Starts our first page.
       CGContextBeginPage (pdfContext, &pdfFrame);  
       // Turn PDF upsidedown
       CGAffineTransform transform = CGAffineTransformIdentity;
       transform = CGAffineTransformMakeTranslation(0,view.bounds.size.height);
       transform = CGAffineTransformScale(transform, 1.0, -1.0);
       CGContextConcatCTM(pdfContext, transform);

       // Calculate amount of y to be displace.
       CGFloat ty = (heightOfPdf*(pageNumber));

       CGContextTranslateCTM(pdfContext,0,-ty);
       [view.layer renderInContext:pdfContext];

       // We are done drawing to this page, let's end it.
       CGContextEndPage (pdfContext);
   }    
}

It creates required number of pages but places the content wrongly. Following figure explains it.enter image description here

Is there anything wrong in my code?

Sam
  • 902
  • 8
  • 16
  • Curious how things work if you take your subview out of the ScrollView? – bentford Nov 26 '11 at 21:02
  • The portions u need to add to pdf pages put in seperate views inside the scroll and render tht view to the pdf context – Lithu T.V Sep 13 '12 at 12:33
  • 1
    Assuming one answer solved this or you found a solution, can you accept or enter it to close the open question? – David H May 05 '13 at 12:51

6 Answers6

1

Found this link to render a PDF, it says about multiple pages but haven't shown an implementation. It doesnt straight away answer to your question but it tells a simpler method to render a pdf with much less translation and transforms.

Render PDF

Generate Multipage PDF -anoop

anoop4real
  • 7,598
  • 4
  • 53
  • 56
1

The portions you need to add to pdf pages put in seperate views inside the scroll and render tht view to the pdf context

OR

Just find the correct dimensions and draw using the CG method:

        UIImage *Logo=[UIImage imageNamed:@"small-logo-left-top130_133.png"];
    CGPoint drawingLogoOrgin = CGPointMake(5,5);

    UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
    UIGraphicsBeginPDFPageWithInfo(pageFrame, nil);
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();
    [Logo drawAtPoint:drawingLogoOrgin];

There are a lot of drawing methods to draw pdf. You can use that to draw all the contents.

mkhilani
  • 9
  • 4
Lithu T.V
  • 19,955
  • 12
  • 56
  • 101
1

This github project can definitely help you.

- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx {
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index + 1);
CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
                                        CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform);
CGContextDrawPDFPage(ctx, page);

}

YogiAR
  • 2,207
  • 23
  • 44
  • Is it possible to change the font and fontsize of the pdf while being added to the context?... Or are there any other ways of changing the font or font size in a pdf?.. – iSeeker Feb 05 '14 at 12:22
1

You could consider using a UIScrollView to layout your separate PDF pages. The following method loads each PDF page in a view (PDFView) and adds it to the scroll view content in a centered fashion:

- (void) loadPDFAtPath:(NSString *)path
{
    NSURL *pdfUrl = [NSURL fileURLWithPath:path];
    CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfUrl);

    float height = 0.0;

    for(int i = 0; i < CGPDFDocumentGetNumberOfPages(document); i++) {
        CGPDFPageRef page = CGPDFDocumentGetPage(document, i + 1);
        PDFView *pdfView = [[PDFView alloc] initPdfViewWithPageRef:page];

        CGRect pageSize = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
        pv.frame = CGRectMake((self.frame.size.width / 2.0) - pageSize.size.width / 2.0, height, pageSize.size.width, pageSize.size.height);
        height += pageSize.size.height + SOME_SPACE_IN_BETWEEN_PAGES;

        // self is a subclass of UIScrollView
        [self addSubview:pdfView];
        [pdfView setNeedsDisplay];
    }

    CGPDFDocumentRelease(document);
    [self setContentSize:CGSizeMake(self.frame.size.width, height)];
}

In this case, PDFView is responsible for rendering a single CGPDFPageRef in its drawRect or drawLayer implementation.

jverrijt
  • 696
  • 4
  • 10
1

I don't think you need the code which flips the PDF upside down. I've done this before (manual pagination, but without a scroll view) and never had to flip the context vertically. My main concern is that you are doing it on every iteration - if you have a valid reason for flipping it, you probably don't need it in the loop, but just once before the loop begins. Also the code CGContextTranslateCTM(pdfContext,0,-ty); might need to be replaced with CGContextTranslateCTM(pdfContext,0,heightOfPdf);

If that doesn't work, try UIGraphicsBeginPDFPage(); instead of CGContextBeginPage(), that's the only major difference between your code and mine.

zeroimpl
  • 2,746
  • 22
  • 19
0

this might help you.

- (void) renderPageAtIndex:(NSUInteger)index inContext:(CGContextRef)ctx 
{
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, index + 1);
CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
                                    CGContextGetClipBoundingBox(ctx));
CGContextConcatCTM(ctx, transform);
CGContextDrawPDFPage(ctx, page);
} 
iCode
  • 39
  • 7