1

您好,我已按照本指南在 pdf 文件上编写文本。本指南可能较旧,但遵循与苹果文档中相同的方法

到目前为止我做了什么:

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


    //http://stackoverflow.com/questions/6988498
    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);

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

4

2 回答 2

1

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

这两个函数通常在 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 解析器软件的人的角度来看,您还希望将保存/恢复对的数量保持在您实际需要的数量。不要不必要地使用它们:)

于 2016-03-01T10:57:39.600 回答
0

答案在本教程的第 2 部分。绘制文本后应重置上下文。

CGContextTranslateCTM(currentContext, 0, 100);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Draw the frame.
CTFrameDraw(frameRef, currentContext);
/*NEW!*/
CGContextScaleCTM(currentContext, 1.0, -1.0);
于 2016-03-01T09:28:31.357 回答