I have this code here that takes my UIView in puts it into a PDF. My issue I am having is that my view is a detail view controller and is scrollable and the PDF only gets what inside the detail view controller at that time and not a full view, if I move around in the detail view, it will capture whatever part I am on, not the full thing. Is what I am trying to do possible?
- (IBAction)Share:(id)sender {
NSMutableData *pdfData = [NSMutableData data];
// Points the pdf converter to the mutable data object and to the UIView to be converted
UIGraphicsBeginPDFContextToData(pdfData, spreadSheet.bounds, nil);
UIGraphicsBeginPDFPage();
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
[spreadSheet.layer renderInContext:pdfContext];
// remove PDF rendering context
UIGraphicsEndPDFContext();
// Retrieves the document directories from the iOS device
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:@"test.pdf"];
// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
UIActivityViewController * activityController = [[UIActivityViewController alloc] initWithActivityItems:@[pdfData] applicationActivities:nil];
UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:activityController];
[popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width - 36, 60, 0, 0)inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
UPDATE
I have been really struggling with this, I can't get the full view into a PDF, I have also been thinking of going to route of taking my NSMutableArray and my NSArray which is the data used in my UIView and try to covert that into a PDF but that sounds very time consuming to make format it nicely, unless someone knows of way to do that. I guess I am confused on which route I should take.
From this
My issue I am having is that my view is a detail view controller and is scrollable and the PDF only gets what inside the detail view controller at that time and not a full view.
Looks like the problem is your content in view is scrollable and you pdf you creating is only capture the visible area.
Here is your problem
UIGraphicsBeginPDFContextToData(pdfData, spreadSheet.bounds, nil);
You need to fix it you need to give it the scrollable view (UITableView,UICollectionView or Scrollview) content size bounds here is how you do it.
-(NSData*)pdfDataFromTableViewContent
{
NSMutableData *pdfData = [NSMutableData data];
//The real size, not only the visible part use your scrollable view ((UITableView,UICollectionView or Scrollview))
CGSize contentSize = self.tableView.contentSize;
CGRect tableViewRealFrame = self.tableView.frame;
//Size tableView to show the whole content
self.tableView.frame = CGRectMake(0, 0, contentSize.width, contentSize.height);
//Generate PDF (one page)
UIGraphicsBeginPDFContextToData(pdfData,self.tableView.frame, nil);
UIGraphicsBeginPDFPage();
[self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIGraphicsEndPDFContext();
//Resize frame
self.tableView.frame = tableViewRealFrame;
return pdfData;
}
The above code will generates one page. For more pages use following code
//MultiPage
CGRect mediaBox = self.tableView.frame;
CGSize pageSize = CGSizeMake(self.view.frame.size.width, 800);
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
NSInteger currentPage = 0;
BOOL done = NO;
do {
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0.0, pageSize.width, pageSize.height), nil);
CGContextTranslateCTM(pdfContext, 0, -(pageSize.height*currentPage));
[self.view.layer renderInContext:pdfContext];
if ((pageSize.height*(currentPage+1)) > mediaBox.size.height) done = YES;
else currentPage++;
} while (!done);
UIGraphicsEndPDFContext();
You can also look into this working project ScrollViewToPDF. It uses same scrollview's layer renderInContext but here PDF is created according to your requirement such as one page PDF or multiple page PDF. It captures all visible as well as invisible part of scrollView
Rendering something into a context only renders what is currently in the view hierarchy. That means that if you're using a UITableView
or UICollectionView
, not every cell that represents your data is in the hierarchy at any given time. If it were me I would try temporarily setting the view to have a massive frame so that everything would be in the hierarchy. If that didn't work I'd be writing a custom view that on request could layout everything for all the data and then reset to a more efficient layout after the rendering was complete.
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