上下文绘图 + 分页

54

我正在尝试将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

我的代码有什么问题吗?


如果您将子视图从ScrollView中移除,想知道事物的工作原理吗? - bentford
将需要添加到PDF页面的部分放在滚动视图内的单独视图中,并将该视图呈现到PDF上下文中。 - Lithu T.V
1
假设有一个答案解决了这个问题,或者你找到了解决方案,你能接受或输入它来关闭这个未解决的问题吗? - David H
6个回答

1

这个 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);

}


在将PDF添加到上下文中时,是否可以更改其字体和字号?还是有其他方法可以更改PDF中的字体或字号? - iSeeker

1

您需要添加到PDF页面的部分,请将其放在滚动视图中的单独视图中,并将该视图呈现到PDF上下文中。

或者

只需找到正确的尺寸并使用CG方法进行绘制:

        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

发现了一个渲染PDF的链接,它提到了多页,但没有展示实现。它并没有直接回答你的问题,但它告诉了一种更简单的方法来渲染PDF,需要更少的转换和变换。

渲染PDF

生成多页PDF -anoop


1

我认为你不需要翻转PDF的代码。我以前也做过这个(手动分页,但没有滚动视图),从来没有必要垂直翻转上下文。我的主要关注点是,如果你有一个有效的理由来翻转它,你可能不需要在循环中这样做,而只需要在循环开始之前执行一次。此外,代码CGContextTranslateCTM(pdfContext,0,-ty);可能需要替换为CGContextTranslateCTM(pdfContext,0,heightOfPdf);

如果这不起作用,请尝试使用UIGraphicsBeginPDFPage();代替CGContextBeginPage(),这是你的代码和我的代码之间唯一的主要区别。


1
你可以考虑使用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 负责在其 drawRect 或 drawLayer 实现中呈现单个的 CGPDFPageRef

0

这可能会对你有所帮助。

- (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
和Rakesh的评论有什么不同? - kpower

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接