I am attempting to convert some text files into a pdf. Now the easiest thing in the world right now is to simply combine all of the text from the files into a single string and then use the iOS documentation here to render it into a single pdf. The trouble is, these are large text files; together they can equal well over 90 pages. Therefore I will need to add in some hyperlinks so I can create a table of contents at the top and the user can quickly move to the beginning of each text file rather than have to scroll through 60 pages to get to where they want to go.
Problem is, if I combine the txt files into a single string, I have no way of knowing when each file will end while it is paginating, therefore I wanted to add the files separately to the pdf before finally publishing it. Problem is, at best only the last txt file will show up rendered, most likely because it is overwriting the previous ones. Below is my code, any ideas?
- (void)savePDFFile:(NSString *)file_Name
{
// NSArray *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *homeDir = NSHomeDirectory();
NSString *saveDirectory = [NSString stringWithFormat: @"%@/%@", homeDir, @"Documents/"];
NSArray *fileAr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:saveDirectory error:nil];
// NSString *text = @"";
// NSMutableArray *textArray = [[NSMutableArray alloc] init];
NSInteger currentPage = 0;
NSString *completeString = @"";
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];
}
}
for (NSString *string in fileAr) {
if([string hasSuffix:@"txt"]){
NSString *file = [NSString stringWithFormat: @"%@/%@", saveDirectory, string];
NSString *text =[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];
// Prepare the text using a Core Text Framesetter
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, (CFStringRef)text, NULL);
if (currentText) {
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)currentText);
// CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
if (framesetter) {
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);
BOOL done = NO;
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);
// Release the framewetter.
CFRelease(framesetter);
CFRelease(currentText);
}
}
// Close the PDF context and write the contents out.
UIGraphicsEndPDFContext();
} else {
NSLog(@"Could not create the framesetter needed to lay out the atrributed string.");
}
// Release the attributed string.
}
}
// 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, 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, 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;
}