2016-03-01 36 views
1

你好我跟着这guide写在pdf文件上的文字。本指南也许老了,但遵循同样的方法,因为在apple docs在pdf上书写文字ios

我迄今所做的:

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]; 
} 

问题是它打印这个: enter image description here

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

CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity); 

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

回答

1

CGContextSaveGStateCGContextRestoreGState看看这里从苹果的文档削波和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解析器软件的人的角度来看,您还希望将保存/恢复对的数量保持为您实际需要的数量。不要不必要地使用它们:)

+0

完美的作品,谢谢! – Sanandrea

+0

一个问题:我认为'CGContextSetTextMatrix(currentContext,CGAffineTransformIdentity);'会恢复上下文。如果情况并非如此,为什么它需要呢? – Sanandrea

+1

PDF成像模型的问题是涉及到文本时存在两个不同的矩阵。你有文本矩阵(可以设置,但只适用于文本)和全局CTM(不能设置,只能附加到)。您的翻译和缩放功能使用CTM。通常这是用于翻转坐标系的坐标系(当iOS和PDF坐标系沿Y轴倒置时)。 –

0

答案位于教程的part 2。在绘制文本后,上下文应该重置。 https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/#//apple_ref/c/func/CGContextSaveGState

这两个功能在PDF文件通常用于支架修改当前的图形状态(包括一切从颜色设置:

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

更好的方法是使用“CGContextSaveGState”和“CGContextRestoreGState”。这节省了你的“工作空间”的副本,让你做任何你想做的事情,然后让你重置它到你的位置。远远好于继续做浮点计算来回翻转...... –

+0

我明白了......请回答这个问题,我会接受你的。 – Sanandrea

+0

我很乐意这样做... –