0

いくつかの異なるテキスト ファイルを取得してそれらをつなぎ合わせ、それらから pdf を作成するアプリを構築しています。各ファイルのテキストにハイパーリンクを追加できるように、ファイルのテキストを個別に追加する必要がありました。ある程度の進歩があり、ほぼ正確に表示されるようになりましたが、CTFramesetterCreateWithAttributedString のサイズが正しくないようです。

たとえば、3 つのファイルのうち最初のファイルは表示が多すぎます。つまり、テキストが終了した後、その後に空白のページが続きます。2 番目のテキスト ファイルは問題なく表示されますが、3 番目のテキスト ファイルには最初から大きなチャンクがありません。ファイルがレンダリングされる順序を逆にしても同じ問題が発生するため、ファイル自体とは何の関係もないと思います。最初のファイル (どちらのファイルでも) には最後に空白のページがあり、3 番目のファイルには最初のページがほとんどありません。この現象の原因を知っている人はいますか?

- (void)savePDFFile:(NSString *)file_Name
{ 
 NSString *homeDir = NSHomeDirectory();
 NSString *saveDirectory = [NSString stringWithFormat: @"%@/%@", homeDir, @"Documents/"]; 


 NSArray *fileAr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:saveDirectory error:nil];
 NSMutableArray *textArray = [[NSMutableArray alloc] init];
 NSInteger currentPage = 0;
 NSInteger currentFile = 0;


 for (NSString *string in fileAr) {
    if([string hasSuffix:@"txt"]){
        NSString *file = [NSString stringWithFormat: @"%@/%@", saveDirectory, string];
        NSString *text =[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];
        completeString = [NSString stringWithFormat:@"%@%@", completeString, text];
    }
 }

        NSString* pdfFileName = file_Name;

        // Create the PDF context using the default page size of 612 x 792.
        UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);


        CFRange currentRange = CFRangeMake(0, 0);
        for (NSString *string in textArray){
        BOOL done = NO;
            NSString *thisText = [textArray objectAtIndex:currentFile];
            CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, (CFStringRef)thisText, NULL);                                
            CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)currentText);
            currentPage = currentPage;
        do {
            // Mark the beginning of a new page.
            UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

            // Draw a page number at the bottom of each page
            currentPage++;
            [self drawPageNumber:currentPage];



            // Render the current page and update the current range to
            // point to the beginning of the next page.
            currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:framesetter];
            // If we're at the end of the text, exit the loop.
            if (currentRange.location == CFAttributedStringGetLength((CFAttributedStringRef)currentText))
                done = YES;

        } while (!done);
            currentFile ++;
            CFRelease(framesetter);
            CFRelease(currentText);
        }

        // Close the PDF context and write the contents out.
        UIGraphicsEndPDFContext();


}


// Use Core Text to draw the text in a frame on the page.
- (CFRange)renderPage:(NSInteger)pageNum withTextRange:(CFRange)currentRange
   andFramesetter:(CTFramesetterRef)framesetter
  {
 // 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);

// Create a path object to enclose the text. Use 72 point
// margins all around the text.
CGRect    frameRect = CGRectMake(72, 72, 500, 648);
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);

// Get the frame that will do the rendering.
// The currentRange variable specifies only the starting point. The framesetter
// lays out as much text as will fit into the frame.
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, 792);
CGContextScaleCTM(currentContext, 1.0, -1.0);

// Draw the frame.
CTFrameDraw(frameRef, currentContext);

// Update the current range based on what was drawn.
currentRange = CTFrameGetVisibleStringRange(frameRef);
currentRange.location += currentRange.length;
currentRange.length = 0;
//    CFRelease(frameRef);

return currentRange;
}
4

1 に答える 1

0

私はそれを理解しました。

「currentPage = currentPage;」を配置しました。私のコードでは、フレームセッターが設定された後にブレークポイントを配置する場所を確保して、それを見ることができるようにしました。まだデバッガを完全にマスターしていません。明らかに問題は発生していませんでしたが、そのコード行を「currentRange.location = 0;」に置き換えて、各ループの後に範囲をリセットしました。問題が解決しました。奇妙なことに、もともと問題を引き起こしていたのは currentRange のリセットでした。

とにかく、上記の変更と、この質問に対する 2 番目の回答 (最後の 4 行を除く) により、問題は解決しました!

于 2012-06-13T16:25:32.633 に答える