在 pdf 上书写文本 ios

Writing text on pdf ios

你好我已经关注了这个guide to write text on pdf file. This guide maybe old but follows the same approach as in apple docs

到目前为止我做了什么:

PdfCreator.m


const int A4_WIDTH = 612;
const int A4_HEIGHT = 792;

@interface PdfCreator()

@property (nonatomic, assign) double currentHeight;


@end

@implementation PdfCreator


- (void) createPdfWithName:(NSString*)name{
    // Create the PDF context using the default page size of 612 x 792.
    UIGraphicsBeginPDFContextToFile(name, CGRectZero, nil);
    // Mark the beginning of a new page.
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, A4_WIDTH, A4_HEIGHT), nil);

    self.currentHeight = 0;
}
- (void) printTrip:(Trip*) trip{

    // Get the graphics context.
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    // Put the text matrix into a known state. This ensures
    // that no old scaling factors are left in place.
    CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

    NSString* textToDraw = @"Hello World";
    CFStringRef stringRef = (__bridge CFStringRef)textToDraw;
    // Prepare the text using a Core Text Framesetter
    CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, NULL);

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);


    //
    CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(
                                                                        framesetter, /* Framesetter */
                                                                        CFRangeMake(0, textToDraw.length), /* String range (entire string) */
                                                                        NULL, /* Frame attributes */
                                                                        CGSizeMake(A4_WIDTH, CGFLOAT_MAX), /* Constraints (CGFLOAT_MAX indicates unconstrained) */
                                                                        NULL /* Gives the range of string that fits into the constraints, doesn't matter in your situation */
                                                                        );

    CGRect frameRect = CGRectMake(0, 0, suggestedSize.width, suggestedSize.height);
    CGMutablePathRef framePath = CGPathCreateMutable();
    CGPathAddRect(framePath, NULL, frameRect);

    // Get the frame that will do the rendering.
    CFRange currentRange = CFRangeMake(0, 0);
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
    CGPathRelease(framePath);



    // Core Text draws from the bottom-left corner up, so flip
    // the current transform prior to drawing.


    CGContextTranslateCTM(currentContext, 0, 100);
    CGContextScaleCTM(currentContext, 1.0, -1.0);
    // Draw the frame.
    CTFrameDraw(frameRef, currentContext);

    CFRelease(frameRef);
    CFRelease(stringRef);
    CFRelease(framesetter);

}

- (void) endFile{
    UIGraphicsEndPDFContext();
}



@end

现在我在另一个模型文件中这样使用它:

PdfCreator *pdf = [[PdfCreator alloc] init];
[pdf createPdfWithName:documentDirectoryFilename];

for (Trip *t in self.trips) {
    [pdf printTrip:t];
}
[pdf endFile];

NSURL *URL = [NSURL fileURLWithPath:documentDirectoryFilename];

if (URL) {
    // Initialize Document Interaction Controller
    self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:URL];

    // Configure Document Interaction Controller
    [self.documentInteractionController setDelegate:self];

    // Preview PDF
    [self.documentInteractionController presentPreviewAnimated:YES];
}

问题是它打印了这个:

我注意到,如果我只调用一次 printTrip: 方法,则只会打印一个 HelloWorld 标签并位于正确的位置。连续调用在顶部打印镜像文本。这很奇怪,因为这一行

CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

应该重置比例因子。任何帮助将不胜感激。

答案可在教程的 part 2 中找到。上下文应该在绘制文本后重置。

CGContextTranslateCTM(currentContext, 0, 100);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Draw the frame.
CTFrameDraw(frameRef, currentContext);
/*NEW!*/
CGContextScaleCTM(currentContext, 1.0, -1.0);

在此处查看 Apple 关于 CGContextSaveGStateCGContextRestoreGState 的文档: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/#//apple_ref/c/func/CGContextSaveGState

这两个函数常用于 PDF 文件中以将对当前图形状态的修改括起来(包括从颜色设置到裁剪和 CTM 或当前变换矩阵的所有内容)。

使用您的代码:

CGContextSaveGState(currentContext); /// A
CGContextTranslateCTM(currentContext, 0, 100);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Draw the frame.
CTFrameDraw(frameRef, currentContext);
CGContextRestoreGState(currentContext); /// B

在 B 点,您现在回到了 A 点的确切位置。

您可以嵌套这些,它是作为堆栈实现的。不过,您必须小心保持它们的平衡。从编写 PDF 解析器软件的人的角度来看,您还希望将保存/恢复对的数量保持在您实际需要的数量。不要不必要地使用它们:)