2016-03-01 37 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

我很樂意這樣做... –