iOS:从 UIView 创建 PDF

发布于 2024-12-06 06:53:43 字数 621 浏览 0 评论 0原文

我正在尝试从 UIView 创建 PDF,其中可能包含图像、标签等。 我已经检查了参考( GeneratePDF)并且我还知道 renderInContext: 方法,该方法可用于将 UIView 的内容绘制到 PDF 上下文上。

我使用 renderInContext: 创建 PDF。然而,图像和文本失去了保真度。即图像不能单独选择&在生成的 PDF 中无法选择/复制文本等。它与从 UIView 快照创建的 PDF 一样好/坏。

我的问题是,我是否必须绘制文本和内容?单独的图像来实现我想要的(使用 CGContextShowTextAtPoint 和 CGContextDrawImage )?

如果是,那么我该如何扫描 UIView 中的文本和内容?图像?假设我从外部收到 UIView我不知道其内容。

I am trying to create a PDF from a UIView which may contain images, labels, etc.
I have checked the reference ( GeneratingPDF) and I am also aware of the renderInContext: method, which can be used to draw the UIView's content onto the PDF context.

I used renderInContext: to create a PDF. However, the images and the text lost their fidelity. i.e. The images were not selectable individually & the text could not be selected/copied, etc. in the resulting PDF. It was as good/bad as the PDF created from a snapshot of the UIView.

My question is, do I have to draw the texts & images individually to achieve what I want (using CGContextShowTextAtPoint & CGContextDrawImage)?

If yes, then how do I go about scanning the UIView for texts & images? Assume that I receive the UIView from outside & am not aware of its contents.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

り繁华旳梦境 2024-12-13 06:53:43

我很幸运,只是遍历我的视图层次结构,并自己调用 -drawRect: 。在每个视图之前您都需要进行一些设置,例如翻译 ctm 和清除文本矩阵,但是当您为每个视图完成这些操作后,您可以执行以下操作:

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

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

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

I've had a moderate amount of luck just walking my view hierarchy, and calling -drawRect: myself. There's a bit of set up that you've got do before each, like translating the ctm and clearing the text matrix, but when you've done that for each view, you can do this:

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

The PDF it generates is vector based -- not just a flat bitmap, so it scales nicely and you can select the text in a viewer/browser. This only works on plain vanilla custom drawing and very simple stuff like UILabels. I doubt it would work with more complex UIKit objects (I'm thinking table views and scroll views). Also, you would need extra work for UIImageViews (which I'm guessing set the contents property of the layer with a CGImageRef), and if you've got other layer based attributes and transforms -- even more work.

Hopefully Apple will give us a better solution than maintaining parallel draw code!

深海不蓝 2024-12-13 06:53:43

您确实必须使用诸如 CGContextShowTextAtPoint 之类的函数将文本/图像单独绘制到 CGContextRef 中(查看 CGPDFContextCreateWithURL )。虽然理论上您可以扫描 UIView 中的图像/标签,但如果您从头开始绘制布局会更好。您必须有某种方法来知道 UIView 中应该包含哪些元素。尽管代码会有很大不同,但从逻辑上讲,您应该以与以编程方式绘制 UIView 而不是从笔尖加载它相同的方式处理它。

如果你真的想扫描你的 UIView,你可以这样做:

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

You do indeed have to draw the texts/images individually into a CGContextRef (look at CGPDFContextCreateWithURL) using functions like CGContextShowTextAtPoint. While you could theoretically scan your UIView for images/labels, it would be better if you just draw the layout from scratch. You must have some way to know what elements should be in the UIView. Although the code will be very different, logically you should approach it the same way you would if you were going to draw the UIView programmatically instead of loading it from a nib.

If you really want to scan your UIView, you could do something like this:

for(UIView *subview in parentView.subviews) {
 if([subview isKindOfClass:[UIImageView class]]) {
  ...
 } else if([subview isKindOfClass:[UITextView class]]) {
  ...
 } else if([subview isKindOfClass:[UILabel class]]) {
  ...
 }
}
梦里人 2024-12-13 06:53:43

尝试,

{
   //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));


}

try,

{
   //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));


}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文