iOS:从UIView创建PDF

3
我想从一个包含图片、标签等的UIView创建PDF文档。我已查阅相关参考资料(GeneratingPDF),也知道可以使用renderInContext:方法将UIView的内容绘制到PDF上下文中。
我使用了renderInContext:来创建PDF文档,但是图片和文本在生成的PDF文档中失真了,即图片不能单独选择,文本也无法选择/复制等操作。生成的PDF与从UIView快照创建的PDF一样好/坏。
我的问题是,我是否必须逐个绘制文本和图像以达到预期效果(使用CGContextShowTextAtPointCGContextDrawImage)?
如果是,那么如何扫描UIView以查找文本和图像呢?假设我从外部接收到UIView并不知道它的具体内容。
3个回答

2

我曾经尝试过直接遍历视图层次结构并手动调用-drawRect:方法,这样做的效果还不错。在每次调用之前需要进行一些设置,比如翻译ctm和清除文本矩阵,但是当你对每个视图都完成了这些设置之后,就可以像这样操作:

UIGraphicsPushContext(ctx);
[self drawRect:self.frame];
UIGraphicsPopContext();

它生成的PDF是基于矢量的,而不仅仅是一个平面位图,因此可以很好地缩放,并且您可以在查看器/浏览器中选择文本。这仅适用于普通香草自定义绘图和非常简单的内容,例如UILabels。我怀疑它是否适用于更复杂的UIKit对象(我正在考虑表视图和滚动视图)。此外,您需要额外的工作来处理UIImageViews(我猜测它们使用CGImageRef设置层的内容属性),如果您有其他基于层的属性和变换,则需要更多的工作。

希望苹果能给我们一个比维护并行绘图代码更好的解决方案!


这个UIView类别很好用-我相信它使用了你的策略: https://github.com/mruegenberg/uiview-hierarchical-drawing。需要记住的一件事是,如果您正在使用CALayers,则需要添加代码来显式地写入上下文。请参见此答案: http://stackoverflow.com/questions/13783971/maintain-vector-graphics-when-rendering-calayer-into-pdf-output - jeffmax

1

您确实需要使用类似于CGContextShowTextAtPoint的函数将文本/图像单独绘制到CGContextRef中(请参阅CGPDFContextCreateWithURL)。虽然您可以从理论上扫描UIView以查找图像/标签,但最好还是从头开始绘制布局。您必须知道UIView中应该包含哪些元素。虽然代码会非常不同,但在逻辑上,您应该采用与以编程方式绘制UIView相同的方式来处理它,而不是从一个nib文件中加载它。

如果您真的想扫描UIView,可以尝试以下方法:

for(UIView *subview in parentView.subviews) {
 if([subview isKindOfClass:[UIImageView class]]) {
  ...
 } else if([subview isKindOfClass:[UITextView class]]) {
  ...
 } else if([subview isKindOfClass:[UILabel class]]) {
  ...
 }
}

谢谢你,Michael!那么,你确定在这种情况下不能使用 renderInContext: 吗?我在考虑如果 UIView 具有花哨的多彩背景之类的情况可能会很难绘制。 - Akshay
是的,我非常确定。不久前,我也遇到了这个问题,我的逻辑与你的一样(renderInContext:),然后我尝试搜索一些代码来将UIView绘制成PDF,在最后发现真正的方法是使用CGContext方法并从头开始绘制所有内容在CGContextRef中。 - Michael Frederick
再次感谢你,迈克尔!那么,如果UIView具有渐变背景,该如何绘制呢?此外,我的实际用例是从UIWebView创建PDF,我正在使用它来显示文件(例如ppt或doc),发现文本和图像不作为子视图存在(没有UILabels或UITextViews)。你也试过这个吗?抱歉最初没有明确说明。 - Akshay
1
所以你真的想将ppt或doc转换为PDF?那是完全不同的故事。我不确定该指向哪个方向。在iOS中,我不知道是否有方便的库来完成这项工作。最简单的方法可能是连接到Web服务,让服务器为您执行转换,但我不知道是否符合您的需求。祝你好运! - Michael Frederick
嗨,Michael,能否从opengles视图生成PDF呢?请告诉我这是否可行,以便我可以继续。先谢谢了。 - ravoorinandan

0

尝试,

{
   //read the pdf file

     CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(),     CFSTR("iPhoneAppProgrammingGuide.pdf"), NULL, NULL);
        PDFfile = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
        CFRelease(pdfURL)

    CGPDFPageRef page = CGPDFDocumentGetPage(PDFfile,currentpage);

    context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
    CGContextFillRect(context,self.bounds);   
    CGContextTranslateCTM(context, -1.0, [self bounds].size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(page,  kCGPDFArtBox, [self bounds], 0, true));
    CGContextDrawPDFPage(context, page);    
    CGContextRestoreGState(context);
    //CGAffineTransform transform = aspectFit(CGPDFPageGetBoxRect(page, kCGPDFMediaBox),
                                                CGContextGetClipBoundingBox(context));

      // CGContextConcatCTM(context, transform);
         UIGraphicsBeginImageContext(CGSizeMake(self.bounds.size.width, self.bounds.size.height));


}

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