In the last post I described how to “draw” on iOS, which served me well in getting me started on iOS PDF programming.
Now I will combine Apple’s print tutorial for iOS and what I’ve learned about drawing:
As with “drawing”, writing PDF isn’t that complicated if you sit down and decipher it. And Apple’s print tutorial for iOS does a good job explaining it. But sadly, the tutorial has a bug in this call. The tutorial wrongly writes:
currentRange = [self renderPageWithTextRange:currentRange andFramesetter:framesetter];
instead of the correct:
currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:framesetter];
So I got this part running pretty well with the following code:
- (IBAction)savePDFFile:(id)sender
{
NSString* path = [[NSBundle mainBundle] pathForResource:@”sampleData” ofType:@”plist”];
// get a temprorary filename for this PDF
path = NSTemporaryDirectory();
self.pdfFilePath = [path stringByAppendingPathComponent:
[NSString stringWithFormat:@"%d.pdf",
[[NSDate date]
timeIntervalSince1970] ]];
// Prepare the text using a Core Text Framesetter
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL,
(CFStringRef)textView.text, NULL);
if (currentText) {
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
if (framesetter) {
NSString* pdfFileName = self.pdfFilePath; //[NSString stringWithString:@"test.pdf"];
// 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);
// 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”);
}
}
The problem was that I couldn’t verify if the PDF was written to the iPhone or not. In the next post I will describe how I combined it with code from
Spitzkoff.