Created
January 27, 2016 12:55
-
-
Save bcbroom/8dc68b6c56e7dca72981 to your computer and use it in GitHub Desktop.
Generate a paginated PDF based on a NSString. Adds an image and person's name on the last page. Shared under MIT license.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PDFGenerator.h | |
// | |
// | |
// Created by Brian Broom on 12/10/15. | |
// Copyright © 2015 Brian Broom. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@interface PDFGenerator : NSObject | |
- (NSData *)generateWithAgreementText:(NSString *)agreementText signatureImage:(UIImage *)signatureImage fullName:(NSString *)fullName; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PDFGenerator.m | |
// | |
// | |
// Created by Brian Broom on 12/10/15. | |
// Copyright © 2015 Brian Broom. All rights reserved. | |
// | |
@import UIKit; | |
#import "PDFGenerator.h" | |
#import "Person.h" | |
@implementation PDFGenerator | |
- (NSData *)generateWithAgreementText:(NSString *)agreementText signatureImage:(UIImage *)signatureImage fullName:(NSString *)fullName { | |
// layout text pages | |
UIFont *textFont = [UIFont fontWithName:@"Avenir Next" size:12.0]; | |
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; | |
paragraphStyle.lineHeightMultiple = 1.2; | |
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; | |
NSDictionary *textAttributes = @{ NSParagraphStyleAttributeName : paragraphStyle, NSFontAttributeName : textFont }; | |
NSAttributedString *styledString = [[NSAttributedString alloc] initWithString:agreementText attributes:textAttributes]; | |
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:styledString]; | |
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; | |
layoutManager.usesFontLeading = YES; | |
[textStorage addLayoutManager:layoutManager]; | |
// Create the PDF context using page size of 612 x 792 (8.5x11 at 72dpi). | |
CGSize pageSize = CGSizeMake(612, 792); | |
CGRect pageRect = CGRectMake(0, 0, pageSize.width, pageSize.height); | |
// 0.5" margin top, bottom | |
CGRect pageRectWithoutMargin = CGRectInset(pageRect, 36, 36); | |
CGSize pageSizeWithoutMargin = pageRectWithoutMargin.size; | |
CGPoint textRenderingStartPoint = pageRectWithoutMargin.origin; | |
while ([self needsMorePagesForLayoutManager:layoutManager]) { | |
[self addPageToLayoutManager:layoutManager withSize:pageSizeWithoutMargin]; | |
} | |
// open PDF context | |
NSMutableData *pdfData = [NSMutableData new]; | |
UIGraphicsBeginPDFContextToData(pdfData, pageRect, nil); | |
// render pages | |
for (NSTextContainer *container in layoutManager.textContainers) { | |
UIGraphicsBeginPDFPage(); | |
NSRange glyphRangeForPage = [layoutManager glyphRangeForTextContainer:container]; | |
[layoutManager drawBackgroundForGlyphRange:glyphRangeForPage atPoint:textRenderingStartPoint]; | |
[layoutManager drawGlyphsForGlyphRange:glyphRangeForPage atPoint:textRenderingStartPoint]; | |
} | |
// add image on new page | |
UIGraphicsBeginPDFPage(); | |
[fullName drawAtPoint:CGPointMake(150, 100) withAttributes:textAttributes]; | |
[signatureImage drawInRect:CGRectMake(150, 200, 200, 100)]; | |
// Close the PDF context and write the contents out. | |
UIGraphicsEndPDFContext(); | |
return pdfData; | |
} | |
- (BOOL)needsMorePagesForLayoutManager:(NSLayoutManager *)layoutManager { | |
if (layoutManager.textContainers.count == 0) { | |
return YES; | |
} | |
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:layoutManager.textContainers.lastObject]; | |
NSUInteger numberOfGlyphs = [layoutManager numberOfGlyphs]; | |
if (glyphRange.location + glyphRange.length < numberOfGlyphs) { | |
return YES; | |
} | |
return NO; | |
} | |
- (void)addPageToLayoutManager:(NSLayoutManager *)layoutManager withSize:(CGSize)pageSizeWithoutMargin { | |
NSTextContainer *container = [[NSTextContainer alloc] initWithSize:pageSizeWithoutMargin]; | |
[layoutManager addTextContainer:container]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
good