I want to create a PDF file in iOS ,there should be one table in the PDF, which is filled from one array. I already searched on Google, but didn't succeed. Any help is appreciated
Something like this routine to render the text:
- (CFRange)renderTextRange:(CFRange)currentRange andFrameSetter:(CTFramesetterRef)frameSetter intoRect:(CGRect)frameRect {
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);
CTFrameRef frameRef = CTFramesetterCreateFrame(frameSetter, currentRange, framePath, NULL);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
CGContextTranslateCTM(currentContext, 0, 792);
CGContextScaleCTM(currentContext, 1.0, -1.0);
CTFrameDraw(frameRef, currentContext);
CGContextRestoreGState(currentContext);
CGPathRelease(framePath);
currentRange = CTFrameGetVisibleStringRange(frameRef);
currentRange.location += currentRange.length;
currentRange.length = 0;
CFRelease(frameRef);
return currentRange;
}
And the following code snippet which calls it, assuming you have the context and any fonts etc created and in the appropriate variables. The following loop simply builds up the text line by line into an NSMutableAttributedString
which you can then render:
CTFontRef splainFont = CTFontCreateWithName(CFSTR("Helvetica"), 10.0f, NULL);
CGFloat margin = 32.0f;
CGFloat sink = 8.0f;
NSMutableAttributedString *mainAttributedString = [[NSMutableAttributedString alloc] init];
NSMutableString *mainString = [[NSMutableString alloc] init];
// Ingredients is an NSArray of NSDictionaries
// But yours could be anything, or just an array of text.
for (Ingredient *ingredient in ingredients) {
NSString *ingredientText = [NSString stringWithFormat:@"%@\t%@
\n",ingredient.amount,ingredient.name];
[mainString appendString:ingredientText];
NSMutableAttributedString *ingredientAttributedText =
[[NSMutableAttributedString alloc] initWithString:ingredientText];
[ingredientAttributedText addAttribute:(NSString *)(kCTFontAttributeName)
value:(id)splainFont
range:NSMakeRange(0, [ingredientText length])];
[mainAttributedString appendAttributedString:ingredientAttributedText];
[ingredientAttributedText release];
}
Now you have your array written out with newlines to one NSMutableAttributedString
you can render it, depending on your text you might want to render it out in a loop until the rendered location matches your text length. Something like:
// Render Main text.
CTFramesetterRef mainSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)mainAttributedString);
currentRange = [KookaDIS renderTextRange:currentRange
andFrameSetter:mainSetter
intoRect:pageRect];
// If not finished create new page and loop until we are.
while (!done) {
UIGraphicsBeginPDFPageWithInfo(pageRect, nil);
currentRange = [self renderTextRange:currentRange
andFrameSetter:mainSetter
intoRect:pageRect];
if (currentRange.location >= [mainString length]) {
done = TRUE;
}
}
The above code will need quite a bit of adapting I'm sure as it's hacked out of a project of my own so some variables (like the frame setter) won't exist and you need to close off the PDF context and release variables etc. Note how mainString is used to determine when the text has been rendered out.
It should give a clear enough indication of how to loop around an array or any other group to render an arbitrary length of text into a document.
Slight modifications to the while loop and the one render before entering it will let you render text out in multiple columns too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With