2012-06-13 2 views
0

몇 가지 텍스트 파일을 함께 사용하여 문자열을 작성한 다음 pdf 파일을 작성하는 앱을 만들고 있습니다. 각 파일의 텍스트에 하이퍼 링크를 추가 할 수 있도록 파일의 텍스트를 별도로 추가해야했습니다. 나는 약간의 진전을 이루어 거의 정확하게 표시 할 수 있지만 CTFramesetterCreateWithAttributedString의 크기가 올바르게 지정되지 않은 것 같습니다.iOS CTFramesetterCreateWithAttributedString의 크기가 정확하게 맞지 않습니다.

예를 들어 세 파일 중 첫 번째 파일이 너무 많이 표시됩니다. 즉, 텍스트가 끝난 후 빈 페이지가 나옵니다. 두 번째 텍스트 파일은 잘 표시되지만 세 번째 파일에는 처음부터 큰 덩어리가 없습니다. 나는 그것이 파일이 렌더링되는 순서를 뒤 바꿔도 같은 문제가 발생하기 때문에 파일 자체와 관련이 없다고 나는 믿는다. 첫 번째 파일 (어느 파일이든간에) 끝에는 빈 페이지가 있고 세 번째 파일에는 첫 번째 페이지가 없거나 누락되어 있습니다. 누구든지이 현상을 일으킬 수있는 것을 알고 있습니까?

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

답변

0

나는 그것을 알아 냈습니다.

"currentPage = currentPage;"를 삽입했습니다. 내 코드에서는 프레임 세터를 설정 한 후에 중단 점을 넣을 지점을 갖기 위해 볼 수있었습니다. 디버거를 아직 마스터하지 못했습니다. 분명히 문제를 일으키지 않았지만 코드의 행을 "currentRange.location = 0;"으로 바꾸면 각 루프 이후에 범위가 재설정됩니다. 문제 해결됨. 이상하게도 원래는 문제의 원인이었던 currentRange를 재설정하는 것이 었습니다.

어쨌든, 위에 나열된 변경 사항과 함께 this 질문 (마이너스 마지막 네 줄)에 대한 두 번째 대답과 함께 문제가 해결되었습니다!

관련 문제