Contex Drawing + Pagination - PullRequest
       67

Contex Drawing + Pagination

54 голосов
/ 30 сентября 2011

Я пытаюсь нарисовать содержимое scrollview в PDF контексте и столкнулся с проблемой pagination.

Следующий код, который я использовал:

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

Создает необходимое количество страниц, но неправильно размещает содержимое. Следующая цифра объясняет это. enter image description here

Что-то не так в моем коде?

Ответы [ 6 ]

1 голос
/ 28 февраля 2013

Вы можете использовать UIScrollView для макета отдельных страниц PDF. Следующий метод загружает каждую страницу PDF в виде (PDFView) и добавляет ее к содержимому представления прокрутки по центру:

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

В этом случае PDFView отвечает за рендеринг одного CGPDFPageRef в его реализации drawRect или drawLayer.

1 голос
/ 01 ноября 2012

Этот проект GitHub может определенно помочь вам.

- (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);

}

1 голос
/ 13 сентября 2012

Части, которые необходимо добавить на страницы PDF, помещают в отдельные представления внутри прокрутки и отображают представление в контексте PDF

ИЛИ

Просто найдите правильные размеры и начертите, используя метод компьютерной графики:

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

Существует множество методов рисования для рисования в формате pdf. Вы можете использовать это, чтобы нарисовать все содержимое.

1 голос
/ 02 сентября 2012

Нашел эту ссылку для рендеринга PDF, там написано о нескольких страницах, но реализация не показана.Он не сразу отвечает на ваш вопрос, но предлагает более простой метод рендеринга PDF с гораздо меньшим количеством переводов и преобразований.

Визуализация PDF

Создание многостраничных страницPDF -anoop

1 голос
/ 30 ноября 2011

Не думаю, что вам нужен код, который переворачивает PDF вверх дном. Я делал это раньше (ручное разбиение на страницы, но без представления с прокруткой) и мне никогда не приходилось переворачивать контекст по вертикали. Моя главная проблема заключается в том, что вы делаете это на каждой итерации - если у вас есть веская причина перевернуть его, вам, вероятно, не нужно это в цикле, а только один раз до его начала. Также код CGContextTranslateCTM(pdfContext,0,-ty); может потребоваться заменить на CGContextTranslateCTM(pdfContext,0,heightOfPdf);

Если это не сработает, попробуйте UIGraphicsBeginPDFPage(); вместо CGContextBeginPage(), это единственное существенное различие между вашим кодом и моим.

0 голосов
/ 24 декабря 2012

это может вам помочь.

- (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);
} 
...