如何在iOS上生成带有“真实”文本内容的PDF?

时间:2012-09-23 21:07:00

标签: ios pdf uikit quartz-2d

我想在我的iOS 6应用程序中生成一个好看的PDF。

我试过了:

  • UIView在上下文中渲染
  • 使用CoreText
  • 使用NSString drawInRect
  • 使用UILabel drawRect

这是一个代码示例:

-(CGContextRef) createPDFContext:(CGRect)inMediaBox path:(NSString *) path
{
    CGContextRef myOutContext = NULL;
    NSURL * url;

    url = [NSURL fileURLWithPath:path];
    if (url != NULL) {
        myOutContext = CGPDFContextCreateWithURL ((__bridge CFURLRef) url,
                                                  &inMediaBox,
                                                  NULL);
    }


    return myOutContext;
}

-(void)savePdf:(NSString *)outputPath
{
    if (!pageViews.count)
        return;

    UIView * first = [pageViews objectAtIndex:0];

    CGContextRef pdfContext = [self createPDFContext:CGRectMake(0, 0, first.frame.size.width, first.frame.size.height) path:outputPath];

    for(UIView * v in pageViews)
    {
        CGContextBeginPage (pdfContext,nil);
        CGAffineTransform transform = CGAffineTransformIdentity;
        transform = CGAffineTransformMakeTranslation(0, (int)(v.frame.size.height));
        transform = CGAffineTransformScale(transform, 1, -1);
        CGContextConcatCTM(pdfContext, transform);

        CGContextSetFillColorWithColor(pdfContext, [UIColor whiteColor].CGColor);
        CGContextFillRect(pdfContext, v.frame);

        [v.layer renderInContext:pdfContext];

        CGContextEndPage (pdfContext);
    }

    CGContextRelease (pdfContext);
}

渲染的UIViews只包含一个UIImageView +一堆UILabel(有些带有边框,有些带有边框)。

我还尝试了在stackoverflow上找到的建议:继承UILabel并执行此操作:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    BOOL isPDF = !CGRectIsEmpty(UIGraphicsGetPDFContextBounds());
    if (!layer.shouldRasterize && isPDF)
        [self drawRect:self.bounds]; // draw unrasterized
    else
        [super drawLayer:layer inContext:ctx];
}

但这也没有改变任何事情。

无论我做什么,在预览中打开PDF时,文本部分可以选择为块,但不能选择每个字符的字符,并且缩放pdf显示它实际上是位图图像。

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

我去年这样做的经历是Apple没有提供任何图书馆。我最终导入了一个开源C库(libHaru)。然后我添加了一个函数,用于在视图层次结构中的每个类中输出它。任何带有子视图的视图都会在其子视图上调用render。我的UILabels,UITextFields,UIImageViews,UISwitches等会以文本或图形的形式输出它们的内容。我还为一些视图渲染了背景颜色。

这不是很令人生畏,但是libHaru给了我一些字体问题,所以iirc我最后只使用了默认的字体和字体大小。

答案 2 :(得分:0)

它与UILabel一起很好地工作,除了您必须解决一个错误:

Rendering a UIView into a PDF as vectors on an iPad - Sometimes renders as bitmap, sometimes as vectors