2012-03-01 75 views
3

我從我的iPhone應用程序生成PDF文件,雖然大多數文件只有一個頁面,但我希望能夠檢測文本是否要超出「邊距」,如果是,請將其添加到下一個頁。我對此很陌生,所以不太確定如何做到這一點。如何從textView製作多頁PDF?

以下是代碼。有什麼建議麼?

- (void) drawBorder 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    UIColor *borderColor = [UIColor grayColor]; 

    CGRect rectFrame = CGRectMake(kBorderInset, kBorderInset, pageSize.width-kBorderInset*2, pageSize.height-kBorderInset*2); 

    CGContextSetStrokeColorWithColor(currentContext, borderColor.CGColor); 
    CGContextSetLineWidth(currentContext, kBorderWidth); 
    CGContextStrokeRect(currentContext, rectFrame); 
} 

- (void)drawPageNumber:(NSInteger)pageNumber 
{ 
    NSString* pageNumberString = [NSString stringWithFormat:@"Page %d", pageNumber]; 
    UIFont* theFont = [UIFont systemFontOfSize:12]; 

    CGSize pageNumberStringSize = [pageNumberString sizeWithFont:theFont 
               constrainedToSize:pageSize 
                lineBreakMode:UILineBreakModeWordWrap]; 

    CGRect stringRenderingRect = CGRectMake(kBorderInset, 
              pageSize.height - 40.0, 
              pageSize.width - 2*kBorderInset, 
              pageNumberStringSize.height); 

    [pageNumberString drawInRect:stringRenderingRect withFont:theFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter]; 
} 

- (void) drawHeader:(NSString *)header 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    CGContextSetRGBFillColor(currentContext, 0.0, 0.0, 0.0, 1.0); 

    NSString *textToDraw = header; 

    UIFont *font = [UIFont systemFontOfSize:24.0]; 

    CGSize stringSize = [textToDraw sizeWithFont:font constrainedToSize:CGSizeMake(pageSize.width - 2*kBorderInset-2*kMarginInset, pageSize.height - 2*kBorderInset - 2*kMarginInset) lineBreakMode:UILineBreakModeWordWrap]; 

    CGRect renderingRect = CGRectMake(kBorderInset + kMarginInset, kBorderInset + kMarginInset, pageSize.width - 2*kBorderInset - 2*kMarginInset, stringSize.height); 

    [textToDraw drawInRect:renderingRect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; 
} 

- (void) drawText:(NSString *)bodyText 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 
    CGContextSetRGBFillColor(currentContext, 0.0, 0.0, 0.0, 1.0); 

    NSString *textToDraw = bodyText; 

    UIFont *font = [UIFont systemFontOfSize:14.0]; 

    CGSize stringSize = [textToDraw sizeWithFont:font 
           constrainedToSize:CGSizeMake(pageSize.width - 2*kBorderInset-2*kMarginInset, pageSize.height - 2*kBorderInset - 2*kMarginInset) 
            lineBreakMode:UILineBreakModeWordWrap]; 

    CGRect renderingRect = CGRectMake(kBorderInset + kMarginInset, kBorderInset + kMarginInset + 50.0, pageSize.width - 2*kBorderInset - 2*kMarginInset, stringSize.height); 

    [textToDraw drawInRect:renderingRect 
        withFont:font 
      lineBreakMode:UILineBreakModeWordWrap 
       alignment:UITextAlignmentLeft]; 

} 

- (void) drawLine 
{ 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

    CGContextSetLineWidth(currentContext, kLineWidth); 

    CGContextSetStrokeColorWithColor(currentContext, [UIColor blackColor].CGColor); 

    CGPoint startPoint = CGPointMake(kMarginInset + kBorderInset, kMarginInset + kBorderInset + 40.0); 
    CGPoint endPoint = CGPointMake(pageSize.width - 2*kMarginInset -2*kBorderInset, kMarginInset + kBorderInset + 40.0); 

    CGContextBeginPath(currentContext); 
    CGContextMoveToPoint(currentContext, startPoint.x, startPoint.y); 
    CGContextAddLineToPoint(currentContext, endPoint.x, endPoint.y); 

    CGContextClosePath(currentContext);  
    CGContextDrawPath(currentContext, kCGPathFillStroke); 
} 

- (void) drawImage:(UIImage *)image 
{ 
    //UIImage * demoImage = [UIImage imageNamed:@"demo.png"]; 
    [image drawInRect:CGRectMake((pageSize.width - image.size.width/2)/2, 350, image.size.width/2, image.size.height/2)]; 
} 


- (void) generatePdf: (NSString *)thefilePath :(NSString *) theHeader :(NSString *) theText :(UIImage *) theImage 
{ 

    pageSize = CGSizeMake(612, 792); 
    UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil); 

    NSInteger currentPage = 0; 
    BOOL done = NO; 
    do 
    { 
     //Start a new page. 
     UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil); 

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

     //Draw a border for each page. 
     [self drawBorder]; 

     //Draw text fo our header. 
     [self drawHeader:theHeader]; 

     //Draw a line below the header. 
     [self drawLine]; 

     //Draw some text for the page. 
     [self drawText:theText]; 

     //Draw an image 
     [self drawImage:theImage]; 
     done = YES; 
    } 
    while (!done); 

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

#pragma mark - View lifecycle 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
} 

- (IBAction)generatePdfWithFileName:(id)sender 
{ 
    pageSize = CGSizeMake(612, 792); 
    NSString *fileName = @"test.pdf"; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName]; 

    NSString *header = @"This is the bad ass header section!"; 
    NSString *text = @"There is so much to say here I don't know where to begin...."; 

    [self generatePdf : pdfFileName : header:text:nil]; 
} 

@end 
+2

就我所知,您必須跟蹤您當前的Y座標並更新每個添加的項目。當您處於或接近保證金時,您將開始一個新頁面。如果使用雲服務是一種選擇,您可以嘗試像管理頁面佈局本身的Docmosis。如果你承諾用這樣的代碼來編排文檔,這對你沒有任何幫助。 – 2012-03-01 08:07:03

+0

你可以給我一個想法如何去做這件事? – jroyce 2012-03-01 17:52:29

+0

我會將它添加爲答案,因爲它太大而不能發表評論。 – 2012-03-02 04:20:45

回答

9

的概念在這裏可以看到

[從http://spitzkoff.com/craig/?p=160]

當放置物品,讓身高:

CGSize size = [name sizeWithFont:studentNameFont forWidth:maxWidth lineBreakMode:UILineBreakModeWordWrap]; 
[name drawAtPoint:CGPointMake(kMargin, currentPageY) forWidth:maxWidth withFont:studentNameFont lineBreakMode:UILineBreakModeWordWrap]; 
currentPageY += size.height; 

在適當的點,檢查currentY,如果你決定需要移動到新頁面:

if (size.height + currentPageY > maxHeight) { 
// create a new page and reset the current page's Y value 
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil); 
currentPageY = kMargin; 
} 

我希望有幫助。

+0

太棒了。非常感謝你! – jroyce 2012-03-02 04:40:38

+0

如何保持這種中頻條件? – maniclorn 2012-08-18 13:40:50

+0

這個答案不會告訴一個字符串是否太長。如何將其分解成部分。 – Saad 2015-04-12 00:42:25

1

我是新來的stackoverflow,但我想建議一個簡短的答案「闖入部分長文本視圖」的問題。

我使用的方法肯定不是將文本分解爲多個部分的最有效方式,但它是我找到並且工作的唯一方式。 取文本的一部分,我只是檢查一個循環,然後逐字繪製,如果子文本適合我的頁面,這意味着高度允許。如果整個文本不合適,那麼我的代碼將只繪製找到的部分。例如,我可以將一個長文本分成四頁......至少。 對不起,我缺乏經驗,如果我的答案只是一瞥,「如何」的想法還不夠清楚。

澄清我的答案。我添加了我用來檢查「子文本」所需高度(找到)的方法(每次用添加到「子文本」的單詞檢查)。因爲「sizeWithFont:」自IOS 7以來已被棄用,所以我使用「boundingRectWithSize:」方法。

// Process, that can take long though, to find the next start of the part of a text that hasn't been drawned yet. 

float widthRect; 
widthRect = pageWidth - 2 * leftMargin; 

    - (unsigned int) findNextStartingPos:(NSString *)text withHeight:(float) height 
    { 
     NSString *character; 
     unsigned int pos = 0; 
     unsigned int posFound = 0; 
     unsigned int lastPosFound = 0; 
     BOOL found = NO; 
     NSString *textTest; 
     float heightFound; 

     while (pos <= [text length]-1) 
     { 
      character = [text substringWithRange:NSMakeRange(pos, 1)]; 
      if ([character isEqualToString:@" "] || [character isEqualToString:@"\n"]) 
      { 
       posFound = pos; 
       found = YES; 
      } 

      if (found) 
      { 
       textTest = [text substringWithRange:NSMakeRange(0, posFound)]; 
       heightFound = lroundf([self heightFound:textTest withWidth:widthRect fontSize:fontSizeBody center:NO]); 

       if (heightFound > height) 
       { 
        if (lastPosFound == 0) 
        { 
         posFound = lastPosFound; 
        } else 
        { 
         posFound = lastPosFound + 1; 
        } 
        if (posFound > [text length]-1) posFound = lastPosFound; 
        break; 
       } 
       lastPosFound = posFound; 
      } 
      pos++; 
     } 

     return posFound; 

    } return posFound; 

    } 


// Returns the height needed to draw a text (and to check for space in a page) 
-(float) heightFound:(NSString *)text withWidth:(float)width fontSize:(CGFloat)fontSize center:(BOOL)center 
{ 
    if ([text length] != 0) 
    { 
     UIFont *font = [UIFont fontWithName:@"Helvetica" size:fontSize]; 

     NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 
     paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; 
     if (center) 
     { 
      paragraphStyle.alignment = NSTextAlignmentCenter; 
     } else { 
      paragraphStyle.alignment = NSTextAlignmentLeft; 
     } 
     NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: paragraphStyle}; 

     NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:attributes]; 

     CGRect newRect = [attributedString boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} options:NSStringDrawingUsesLineFragmentOrigin context:nil]; 

     return newRect.size.height; 

    } else { 
     return 0; 
    } 
} 
+0

對不起,如果我的代碼不是精確enoungh。它本來就太長了。 – 2016-03-10 06:50:09

+0

要小心一個以「\ n」結尾的頁面,它需要更多的編碼。 – 2016-03-10 07:07:19

+0

我並不真正尋求「積分聲望」,但由於我是新手,因此有些鼓勵將會受到讚賞。 – 2016-03-10 07:41:44