Question

I am trying to create a multipage PDF. I have followed this tutorial. This is working with a XIB file for static text and then adds a table from code. But the problem I'm having ATM is that when the table is bigger then one page. When the table has more then 9 rows. It should continue on the next page.

This is what I'm doing in code.

+(void)drawPDF:(NSString*)fileName
{
    NSMutableDictionary *mutDictValues = [[[NSUserDefaults standardUserDefaults] objectForKey:@"dicValues"] mutableCopy];
    NSMutableArray *arrSelectedCities = [[mutDictValues objectForKey:@"cities"]mutableCopy ];

    if(arrSelectedCities.count <= 8){
        // If there are only 8 rows --> we can fit everyting on one page !

        // Create the PDF context using the default page size of 612 x 792.
        UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
        // Mark the beginning of a new page.
        UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

        [self drawLabels];
        [self drawLogo];

        int xOrigin = 50;
        int yOrigin = 350;

        int rowHeight = 50;
        int columnWidth = 240;

        int numberOfRows = 9;
        int numberOfColumns = 2;

        [self drawTableAt:CGPointMake(xOrigin, yOrigin) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows andColumnCount:numberOfColumns];

        [self drawTableDataAt:CGPointMake(xOrigin, yOrigin) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows andColumnCount:numberOfColumns withArray:arrSelectedCities];

        // Close the PDF context and write the contents out.
        UIGraphicsEndPDFContext();

    }else{
        // When we have more then 8 rows we should have 2 pages.
        NSLog(@"Create 2 pages");
        // Create the PDF context using the default page size of 612 x 792.
        UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
        // Mark the beginning of a new page.
        UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

        [self drawLabels];
        [self drawLogo];

        int xOrigin = 50;
        int yOrigin = 350;

        int rowHeight = 50;
        int columnWidth = 240;

        int numberOfRows = 9;
        int numberOfColumns = 2;

        [self drawTableAt:CGPointMake(xOrigin, yOrigin) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows andColumnCount:numberOfColumns];

        [self drawTableDataAt:CGPointMake(xOrigin, yOrigin) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows andColumnCount:numberOfColumns withArray:arrSelectedCities];


        // Create the PDF context using the default page size of 612 x 792.
        UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
        // Mark the beginning of a new page.
        UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);


        int xOrigin2 = 50;
        int yOrigin2 = 60;
        int numberOfRows2 = ((arrSelectedCities.count+1)-9);

        [self drawTableAt:CGPointMake(xOrigin2, yOrigin2) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows2 andColumnCount:numberOfColumns];

        [self drawTableDataAt:CGPointMake(xOrigin2, yOrigin2) withRowHeight:rowHeight andColumnWidth:columnWidth andRowCount:numberOfRows2 andColumnCount:numberOfColumns withArray:arrSelectedCities];


    }
    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();
}

Let me explain what I'm doing here. I have an array that should fill up my tableview. If the array is bigger then 8 then I should use 2 pages. Else everything works with one page.

What this does is, it's creating only the second page....

Can anybody help me?

Was it helpful?

Solution

You should not call UIGraphicsBeginPDFContextToFile() again when creating the second page, only UIGraphicsBeginPDFPageWithInfo():

UIGraphicsBeginPDFContextToFile(...); 
UIGraphicsBeginPDFPageWithInfo(...); // start first page
// ...
UIGraphicsBeginPDFPageWithInfo(...); // start second page
// ...
UIGraphicsEndPDFContext();

OTHER TIPS

NSArray *imageArray = [NSArray arrayWithObjects:[UIImage imageNamed:@"3.png"], [UIImage imageNamed:@"4.png"], [UIImage imageNamed:@"5.png"], [UIImage imageNamed:@"3.png"], nil];



NSMutableData *pdfFile = [[NSMutableData alloc] init];
double pageWidth = 0.0;
double pageHeight = 0.0;
UIImage *image;
for (int i = 0; i < [imageArray count]; i++)
{
    image =[UIImage imageWithCGImage:[imageArray[i] CGImage]];
    pageWidth = pageWidth + image.size.width ;
    pageHeight = pageHeight + image.size.height;
}
image =[UIImage imageWithCGImage:[imageArray[0] CGImage]];
CGRect rect;
rect = CGRectMake(0, 0,image.size.width ,image.size.height);
UIGraphicsBeginPDFContextToData(pdfFile, CGRectZero, nil);
for (int i = 0; i < [imageArray count] ; i++)
{
    UIGraphicsBeginPDFPageWithInfo(rect, nil);
    UIImage *contextImage = imageArray[i];
    [contextImage drawInRect:rect];
}
UIGraphicsEndPDFContext();

// save PDF file
NSString *saveFileName = [NSString stringWithFormat:@"%@%fx%f.pdf", @"test", pageWidth, pageHeight];

NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* savePath = [documentDirectory stringByAppendingPathComponent:saveFileName];

if([[NSFileManager defaultManager] fileExistsAtPath:savePath])
{
    [[NSFileManager defaultManager] removeItemAtPath:savePath error:nil];
}
[pdfFile writeToFile: savePath atomically: YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"PDF File created and saved successfully." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];

You don't need to create context for second page (UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil)), you have to only create this page. You should also remember about closing opened page using CGPDFContextEndPage().

- (void)viewDidLoad {
[super viewDidLoad];
[self createPDF];
}

- (void)createPDF {
[self setupPDFDocumentNamed:@"myPdf" Width:850 Height:1100];
[self beginPDFPage];
    }

    - (void)beginPDFPage {
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);

// kPadding will make 20 points margin on both sides of pdf
CGRect textRect = [self addText:@"Line Text Testing" withFrame:CGRectMake(PdfPadding, PdfPadding, 400, 200) fontSize:48.0f];

textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height +PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor blueColor]];

UIImage *anImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://www.phantompeer.com/sitefiles/osx.png"]]];
textRect = [self addImage:anImage atPoint:CGPointMake((pageSize.width/2)-(anImage.size.width/2),textRect.origin.y + textRect.size.height + PdfPadding)];
textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height + PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor redColor]];

textRect = [self addText:@"Line Text Testing" withFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height + PdfPadding, 400, 200) fontSize:48.0f];

textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height +PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor blueColor]];

anImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://www.w3schools.com/css/img_fjords.jpg"]]];
    textRect = [self addImage:anImage atPoint:CGPointMake((pageSize.width/2)-(anImage.size.width/2),textRect.origin.y + textRect.size.height + PdfPadding)];

textRect = [self addLineWithFrame:CGRectMake(PdfPadding, textRect.origin.y + textRect.size.height + PdfPadding, pageSize.width - PdfPadding*2, 4) withColor:[UIColor redColor]];


UIGraphicsEndPDFContext();
[self loadRemotePdf];
    }
-(CGRect)addText:(NSString*)text withFrame:(CGRect)frame fontSize:(float)fontSize {



UIFont *font = [UIFont systemFontOfSize:fontSize];
CGSize stringSize = [text sizeWithFont:font constrainedToSize:CGSizeMake(pageSize.width - 2*20-2*20, pageSize.height - 2*20 - 2*20) lineBreakMode:UILineBreakModeWordWrap];



if((frame.origin.y + stringSize.height + PdfPadding) > pageSize.height) {
    frame = CGRectMake(frame.origin.x, PdfPadding, frame.size.width, frame.size.height);
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
}

float textWidth = frame.size.width;

if (textWidth < stringSize.width)
    textWidth = stringSize.width;
if (textWidth > pageSize.width)
    textWidth = pageSize.width - frame.origin.x;


CGRect renderingRect = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);

[text drawInRect:renderingRect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentLeft];

frame = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);

return frame;
}

-(CGRect)addLineWithFrame:(CGRect)frame withColor:(UIColor*)color {


if((frame.origin.y + frame.size.height+PdfPadding) > pageSize.height) {
    frame = CGRectMake(frame.origin.x, PdfPadding, frame.size.width, frame.size.height);
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
}

CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(currentContext, color.CGColor);

// this is the thickness of the line
CGContextSetLineWidth(currentContext, frame.size.height);
CGPoint startPoint = frame.origin;
CGPoint endPoint = CGPointMake(frame.origin.x + frame.size.width, frame.origin.y);

CGContextBeginPath(currentContext);
CGContextMoveToPoint(currentContext, startPoint.x, startPoint.y);
CGContextAddLineToPoint(currentContext, endPoint.x, endPoint.y);

CGContextClosePath(currentContext);
CGContextDrawPath(currentContext, kCGPathFillStroke);



return frame;
        }


-(CGRect)addImage:(UIImage*)image atPoint:(CGPoint)point {
CGRect imageFrame = CGRectMake(point.x, point.y, image.size.width, image.size.height);

if((imageFrame.origin.y + imageFrame.size.height + PdfPadding) > pageSize.height) {
    imageFrame = CGRectMake(imageFrame.origin.x, PdfPadding, imageFrame.size.width, imageFrame.size.height);
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
}
[image drawInRect:imageFrame];
return imageFrame;
}

- (void) loadRemotePdf
{
CGRect rect = [[UIScreen mainScreen] bounds];
CGSize screenSize = rect.size;


NSString *newPDFName = [NSString stringWithFormat:@"myPdf.pdf"];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:newPDFName];

UIWebView *myWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,screenSize.width,screenSize.height)];
myWebView.autoresizesSubviews = YES;
myWebView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

NSURL *myUrl = [NSURL fileURLWithPath:pdfPath];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myUrl];

[myWebView loadRequest:myRequest];

[self.view addSubview: myWebView];
}

For creating new page in the pdf, use

UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top