IOS: rendering UITableView to PDF

I wrote a pdfGenerator class to render the entire UITableView to create a PDF.

Using:

[pdfGenerator createPDFFromTableview:self.tableView]; 

Class Methods:

 - (void)createPDFFromTableview:(UITableView *)tableview { [tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self renderTableView:tableview]; int rows = [tableview numberOfRowsInSection:0]; int numberofRowsInView = 17; for (int i = 0; i < rows/numberofRowsInView; i++) { [tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(i+1)*numberofRowsInView inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self renderTableView:tableview]; } } - (void)renderTableView:(UITableView*)tableview { UIGraphicsBeginImageContext(tableview.frame.size); [tableview.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *tableviewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIGraphicsBeginPDFPage(); [tableviewImage drawInRect:tableview.frame]; } 

This code scrolls the table view correctly, but it only creates a PDF for the first page, and the rest of the pages are blank! . I have no idea why this is happening, as long as it has to take the current snapshot as it is and display it, but it seems to be done only for the first page. Can someone point out what might be wrong here? Is there a better way to do what I'm trying to achieve?

[EDIT]

The following is the same result:

 int totalRows = [tableview numberOfRowsInSection:0]; int totalVisibleRows = 17; for (int i = 0; i < ceil((float)totalRows/totalVisibleRows); i++) { [tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i * totalVisibleRows inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [pdfGenerator renderTableView:tableview indexPathStart:[NSIndexPath indexPathForRow:i * totalVisibleRows inSection:0] indexPathEnd:[[tableview indexPathsForVisibleRows] lastObject]]; } - (void)renderTableView:(UITableView*)tableview indexPathStart:(NSIndexPath *)startingIndexPath indexPathEnd:(NSIndexPath *)endIndexPath { CGRect rectToDraw = CGRectUnion([tableview rectForRowAtIndexPath:startingIndexPath], [tableview rectForRowAtIndexPath:endIndexPath]); NSLog(@"%@", NSStringFromCGRect(rectToDraw)); UIGraphicsBeginImageContext(rectToDraw.size); [tableview.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *tableviewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIGraphicsBeginPDFPage(); [tableviewImage drawInRect:rectToDraw]; } 

RectToDraw Output:

 {{0, 0}, {768, 720}} {{0, 680}, {768, 720}} {{0, 1360}, {768, 720}} {{0, 2040}, {768, 360}} 
+1
source share
2 answers

I end up creating a view that holds the tableview after scrolling through the table view programmatically. Table view rendering doesn't seem to work after scrolling!

+1
source

Your graphics context is initialized by the UITableView frame, so it will always look at the "first page". The graphical context for the following "pages" will require the context offset of the internal UIScrollView your UITableView . Prohibiting any tricks for direct access to UIScrollView, I suggest you use the [UITableView rectForRowAtIndexPath:] method to get the CGR addresses of the first and last line that you want to draw in the step (i.e. the page) and CGRectUnion to get a rectangle that will include both (and thereby all lines between them). A.

Edit (as noted in the comments): You basically replace the render message in your loop with something like this

 [self renderTableView:tableview indexPathStart:[NSIndexPath indexPathForRow:row inSection:0] indexPathEnd:[[tableview indexPathsForVisibleRows] lastObject]]; 

And your rendering method will look like this:

 - (void)renderTableView:(UITableView*)tableview indexPathStart:(NSIndexPath *)startingIndexPath indexPathEnd:(NSIndexPath *)endIndexPath{ CGRect rectToDraw = CGRectUnion([tableview rectForRowAtIndexPath:startingIndexPath], [tableview rectForRowAtIndexPath:endIndexPath]); NSLog(@"%@", NSStringFromCGRect(rectToDraw)); //... } 

Regarding your question about indexPaths. indexPath.row will not always be 0-16. They will be 0-16, 17-34, 35-51, etc. It also affects your context, i.e. You want to draw a rectangle for the corresponding indexPath rectangle, as this is the β€œplace” where the layer supporting UITableView has backup storage for the graphics currently being displayed. Without knowing your PDF drawing routine, you may also need to check your drawing.

0
source