Нарисуйте изображение после содержимого в файле PDF

В последнее время я много искал для хорошего учебника PDF, документации и т. Д.

Я закончил использовать этот код, но проблем мало.

сценарий

У меня есть представление, которое содержит метку, textView и imageView. Теперь мы будем называть name метки, description textView и image imageView.

Название работает как заголовок.

Описание очень изменчиво, оно может быть от 2 строк до некоторых страниц.

Изображение должно идти в конце текста описания.

Я использую этот код:

 - (void)generatePDF{ NSString *fileName = [NSString stringWithFormat:@"%@.pdf",nameString]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName]; CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, (CFStringRef)descriptionString, NULL); if (currentText) { CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText); if (framesetter) { // Create the PDF context using the default page: currently constants at the size // of 612 x 792. UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil); CFRange currentRange = CFRangeMake(0, 0); NSInteger currentPage = 0; BOOL done = NO; do { // Mark the beginning of a new page. UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth, kDefaultPageHeight), nil); [self drawHeader] // 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); // Close the PDF context and write the contents out. UIGraphicsEndPDFContext(); // Release the framewetter. CFRelease(framesetter); } else { NSLog(@"Could not create the framesetter needed to lay out the atrributed string."); } // Release the attributed string. CFRelease(currentText); } else { NSLog(@"Could not create the attributed string for the framesetter"); } } - (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(22,72, 468, 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, kDefaultPageHeight); 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; } - (void)drawPageNumber:(NSInteger)pageNum { NSString* pageString = [NSString stringWithFormat:NSLocalizedString(@"Page", nil), pageNum]; UIFont* theFont = [UIFont systemFontOfSize:12]; CGSize maxSize = CGSizeMake(kDefaultPageWidth, 72); CGSize pageStringSize = [pageString sizeWithFont:theFont constrainedToSize:maxSize lineBreakMode:UILineBreakModeClip]; CGRect stringRect = CGRectMake(((kDefaultPageWidth - pageStringSize.width) / 2.0), 720.0 + ((72.0 - pageStringSize.height) / 2.0) , pageStringSize.width, pageStringSize.height); [pageString drawInRect:stringRect withFont:theFont]; } 

Я хотел бы знать, как рисовать изображение в конце страницы, сразу после окончания описания.

Я нарисовал заголовок таким образом:

 -(void)drawHeader{ NSString *headerString = nameString; UIFont* theFont = [UIFont boldSystemFontOfSize:15]; CGSize maxSize = CGSizeMake(kDefaultPageWidth, 72); CGSize pageStringSize = [headerString sizeWithFont:theFont constrainedToSize:maxSize lineBreakMode:UILineBreakModeClip]; CGRect stringRect = CGRectMake(22,22,pageStringSize.width,pageStringSize.height); [headerString drawInRect:stringRect withFont:theFont]; } 

и это отображается в начале каждой страницы.

Теперь я не знаю, как нарисовать изображение после содержимого (описания)!

Любая помощь высоко ценится!

Ну, рисование pdf в контексте – это как рисование в холсте.

Лучший способ рисовать текст и изображения, которые являются динамическими по своей природе, – это создавать и использовать методы для рисования, которые возвращают высоту, используемую для рисования на странице, и просто удерживая переменную для вычисления следующей позиции рисования y, увеличивая с возвратом value.Also добавьте отдельную переменную смещения, чтобы проверить рамку страницы.

Чтобы нарисовать изображение в PDF-контексте, вы можете использовать следующий пример. Вы также можете отображать CGImage через Core Graphics, но вы должны рассмотреть поворот холста ( CGContext ), поскольку они будут отображаться вверх-вниз (перевернуто), поскольку начало координат в Core Graphics находится в правом нижнем углу.

 UIImage *gymLogo=[UIImage imageNamed:@"logo.png"]; CGPoint drawingLogoOrigin = CGPointMake(5,5); [gymLogo drawAtPoint:drawingLogoOrigin]; 

Счастливое кодирование 🙂

Сначала вы создаете собственный метод в файле pdf_tutorialViewController.h

 - (void)drawImage:(UIImage *)img atRect:(CGRect)rect inContext:(CGContextRef)ctx; 

/////////////// pdf_tutorialViewController.m файл //////////

и Add UIImage и call drawImage:atRect:inContext: метод в конце вашего метода .

 - (CFRange)renderPage:(NSInteger)pageNum withTextRange:(CFRange)currentRange andFramesetter:(CTFramesetterRef)framesetter { //////////////////////////////////////////////////////////////////////////////////// UIImage *logoimg = [UIImage imageNamed:@"1.png"]; [self drawImage:logoimg atRect:CGRectMake("Your Size") inContext:currentContext]; return currentRange; //////////////////////////////////////////////////////////////////////////////////// } 

И добавьте код

 - (void)drawImage:(UIImage *)img atRect:(CGRect)rect inContext:(CGContextRef)ctx { UIImage *myImage = (UIImage *)img; [myImage drawInRect:rect]; //[myImage release]; } 

Этот код может быть полезен для вас 🙂

благодаря

Вот подкласс UIView который делает то, что вы хотите …

Вы можете поместить его в UIScrollView . Вызовите -sizeThatFits: чтобы получить правильный размер кадра во время просмотра -layoutSubviews вашего -layoutSubviews . (также для вашего содержимого содержимого содержимого прокрутки).

Обратите внимание, что я включил категорию в UILabel, которая возвращает разумный размер в -sizeThatFits: вы можете предоставить свою собственную реализацию.

view.h

 #import <UIKit/UIKit.h> @interface View : UIView @property ( nonatomic, strong, readonly ) UILabel * descriptionLabel ; @property ( nonatomic, strong, readonly ) UILabel * nameLabel ; @property ( nonatomic, strong, readonly ) UIImageView * pdfImageView ; @property ( nonatomic ) CGPDFDocumentRef pdf ; @end 

View.m

 #import "View.h" @implementation UILabel (SizeThatFits) -(CGSize)sizeThatFits:(CGSize)fitSize { return [ self.text sizeWithFont:self.font constrainedToSize:fitSize ] ; } @end @interface View () @property ( nonatomic, strong, readonly ) UIImage * pdfImage ; @end @implementation View @synthesize descriptionLabel = _descriptionLabel ; @synthesize nameLabel = _nameLabel ; @synthesize pdfImageView = _pdfImageView ; @synthesize pdfImage = _pdfImage ; -(void)dealloc { CGPDFDocumentRelease( _pdf ) ; } -(CGSize)sizeThatFits:(CGSize)size { CGSize fitSize = (CGSize){ size.width, CGFLOAT_MAX } ; CGSize result = { size.width, 0 } ; result.height = [ self.headerLabel sizeThatFits:fitSize ].height + [ self.label sizeThatFits:fitSize ].height + self.pdfImage.size.height * fitSize.width / self.pdfImage.size.width ; return result ; } -(void)layoutSubviews { CGRect bounds = self.bounds ; CGRect slice ; CGRectDivide( bounds, &slice, &bounds, [ self.headerLabel sizeThatFits:bounds.size ].height, CGRectMinYEdge ) ; self.headerLabel.frame = slice ; CGRectDivide( bounds, &slice, &bounds, [ self.label sizeThatFits:bounds.size ].height, CGRectMinYEdge ) ; self.label.frame = slice ; self.pdfImageView.frame = bounds ; } -(void)setPdf:(CGPDFDocumentRef)pdf { CGPDFDocumentRelease( _pdf ) ; _pdf = CGPDFDocumentRetain( pdf ) ; _pdfImage = nil ; } -(UILabel *)descriptionLabel { if ( !_descriptionLabel ) { UILabel * label = [[ UILabel alloc ] initWithFrame:CGRectZero ] ; label.numberOfLines = 0 ; // // ... configure label here // [ self addSubview:label ] ; _descriptionLabel = label ; } return _descriptionLabel ; } -(UILabel *)nameLabel { if ( !_nameLabel ) { UILabel * label = [[ UILabel alloc ] initWithFrame:CGRectZero ] ; label.numberOfLines = 0 ; // // ... configure label here // [ self addSubview:label ] ; _nameLabel = label ; } return _nameLabel ; } -(UIView *)pdfImageView { if ( !_pdfImageView ) { UIImageView * imageView = [[ UIImageView alloc ] initWithFrame:CGRectZero ] ; [ self addSubview:imageView ] ; _pdfImageView = imageView ; } return _pdfImageView ; } -(UIImage *)pdfImage { if ( !_pdfImage ) { CGPDFPageRef page = CGPDFDocumentGetPage( self.pdf, 1 ) ; // 1 indexed CGRect mediaBox = CGPDFPageGetBoxRect( page, kCGPDFMediaBox ) ; UIGraphicsBeginImageContextWithOptions( mediaBox.size, NO, self.window.screen.scale ) ; CGContextRef c = UIGraphicsGetCurrentContext() ; CGContextScaleCTM( c, 1.0f, -1.0f ) ; CGContextTranslateCTM( c, 0.0, -mediaBox.size.height ) ; CGContextDrawPDFPage( c, page ) ; _pdfImage = UIGraphicsGetImageFromCurrentImageContext() ; self.pdfImageView.image = _pdfImage ; UIGraphicsEndImageContext() ; } return _pdfImage ; } @end 

Если вам нужен нижний колонтитул страницы, вы можете добавить еще один UILabel внизу, следуя одному шаблону.

 NSString *fileName = @"myInfo.pdf"; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:fileName]; if ([passwordString length]) { NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:passwordString, kCGPDFContextOwnerPassword, passwordString, kCGPDFContextUserPassword, kCFBooleanFalse, kCGPDFContextAllowsCopying, kCFBooleanFalse, kCGPDFContextAllowsPrinting, nil]; // Providing Password Protection for PDF File UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, dictionary); [dictionary release]; } else { UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil); } UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612.0, heightOfView), nil); //612,792 Width & Height of the pdf page which we want to generate. NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png", 123]]; UIImage *pngImage = [UIImage imageWithContentsOfFile:pngPath]; [pngImage drawInRect:CGRectMake((612 - self.frame.size.width) / 2, 0, self.frame.size.width, heightOfView)]; // Size of the image we want to draw in pdf file. UIGraphicsEndPDFContext(); 
Interesting Posts
Давайте будем гением компьютера.