How to get a UITableView snapshot in PDF format

I have a UITableView that is populated with some data, but since it contains data that is larger than the visible screen area, I was able to get only a snapshot, I want to know if in any other way I can get the whole snapshot of the table in pdf. This is what I tried thanks

 - (IBAction)clickMe:(id)sender { UIView *viewToRender = self.myTableView; CGPoint contentOffset = self.myTableView.contentOffset; UIGraphicsBeginImageContext(viewToRender.bounds.size); CGContextRef ctx = UIGraphicsGetCurrentContext(); // KEY: need to translate the context down to the current visible portion of the tablview CGContextTranslateCTM(ctx, 0, -contentOffset.y); [viewToRender.layer renderInContext:ctx]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIImageView *myImage=[[UIImageView alloc]initWithImage:image]; UIGraphicsEndImageContext(); [self createPDFfromUIViews:myImage saveToDocumentsWithFileName:@"PDF Name"]; } - (void)createPDFfromUIViews:(UIView *)myImage saveToDocumentsWithFileName:(NSString *)string { NSMutableData *pdfData = [NSMutableData data]; UIGraphicsBeginPDFContextToData(pdfData, myImage.bounds, nil); UIGraphicsBeginPDFPage(); CGContextRef pdfContext = UIGraphicsGetCurrentContext(); // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData [myImage.layer renderInContext:pdfContext]; // remove PDF rendering context UIGraphicsEndPDFContext(); NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); NSString* documentDirectory = [documentDirectories objectAtIndex:0]; NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:string]; NSLog(@"%@",documentDirectoryFilename); [pdfData writeToFile:documentDirectoryFilename atomically:YES]; } 
+6
source share
5 answers
 UIGraphicsBeginImageContext(self.myTableView.contentSize); [self.myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self.myTableView.layer renderInContext:UIGraphicsGetCurrentContext()]; int rows = [self.myTableView numberOfRowsInSection:0]; int numberofRowsInView = 4; for (int i =0; i < rows/numberofRowsInView; i++) { [self.myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(i+1)*numberofRowsInView inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self.myTableView.layer renderInContext:UIGraphicsGetCurrentContext()]; } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIImageView *myImage=[[UIImageView alloc]initWithImage:image]; UIGraphicsEndImageContext(); [self createPDFfromUIViews:myImage saveToDocumentsWithFileName:@"PDF Name"]; 

I don’t know, but this code works like a charm for me.

+14
source

Here you can do this without scrolling through the tableview. Just increase the scroll height to contentSize. PDF quality is also better if you don't go through UIImage . This is from my UITableView extension in Swift. The code is stolen here and there, so the comments are not always mine.

 func toPDF(fileName: String) -> String { // Don't include scroll indicators in file self.showsVerticalScrollIndicator = false // Creates a mutable data object for updating with binary data, like a byte array let pdfData = NSMutableData() // Change the frame size to include all data let originalFrame = self.frame self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.contentSize.width, self.contentSize.height) // Points the pdf converter to the mutable data object and to the UIView to be converted UIGraphicsBeginPDFContextToData(pdfData, self.bounds, nil) UIGraphicsBeginPDFPage() let pdfContext = UIGraphicsGetCurrentContext(); // Draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData self.layer.renderInContext(pdfContext!) // Remove PDF rendering context UIGraphicsEndPDFContext() // Retrieves the document directories from the iOS device let documentDirectories: NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let documentDirectory = documentDirectories.objectAtIndex(0) let documentDirectoryFilename = documentDirectory.stringByAppendingPathComponent(fileName); // Instructs the mutable data object to write its context to a file on disk pdfData.writeToFile(documentDirectoryFilename, atomically: true) // Back to normal size self.frame = originalFrame // Put back the scroll indicator self.showsVerticalScrollIndicator = true return documentDirectoryFilename } 
+3
source

There are no off-screen cells because they are recycled as soon as they scroll from the visible screen. Instead of taking UITableView screenshots, you should consider creating a PDF version using Core Text. Perhaps you can adapt this example .

+2
source

Based on Vin's answer (can also be used to create snapshots of UIScrollViews):

  UIGraphicsBeginPDFContextToData(pdfData, CGRectMakeWithSize(0, 0, self.productsTable.contentSize), nil); UIGraphicsBeginPDFPage(); [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; [self.productsTable scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO]; [self.productsTable.layer renderInContext:UIGraphicsGetCurrentContext()]; CGFloat screensInTable = self.productsTable.contentSize.height / self.productsTable.height; for (int i = 1; i < screensInTable; i++) { CGPoint contentOffset = CGPointMake(0, i * self.productsTable.height); [self.productsTable setContentOffset:contentOffset animated:NO]; [self.productsTable.layer renderInContext:UIGraphicsGetCurrentContext()]; } UIGraphicsEndPDFContext(); 
+1
source

I think everyone forgets that UITableView is a UIScrollView . No need to calculate cells, height, etc. You can simply create your context using contentSize , set tableView.frame.size = tableView.contentSize and render in context.

See this example.

  UIGraphicsBeginImageContext(tableView.contentSize) let context = UIGraphicsGetCurrentContext() let cachedOffset = CGPoint(x:tableView.contentOffset.x , y:tableView.contentOffset.y) let cachedFrame = tableView.frame tableView.contentOffset = .zero tableView.frame = CGRect(x: 0, y: 0, width: tableView.contentSize.width, height: tableView.contentSize.height) tableView.layer.render(in: context) tableView.frame = cachedFrame tableView.contentOffset = cachedOffset if let image = UIGraphicsGetImageFromCurrentImageContext() { let imageView = UIImageView(image: image) self.createPDF(fromUIViews:myImage saveToDocumentsWithFileName:"PDF Name") } UIGraphicsEndImageContext() 
0
source