I'm trying to save all of the contents of a UIScrollView to a .pdf. I found some tutorials for saving the current view, and they all rely on creating a CGContextRef using UIGraphicsGetCurrentContext()
. Right now, I capture my view with just
CGContextRef context = UIGraphicsGetCurrentContext();
[myView.layer renderInContext:context];
And that works fine for a plain UIView. However, when I try to pass a UIScrollView as myView
, it passes the visible part of the UIScrollView fine, but anything offscreen is just white space. Is there a way I can expand context
somehow to get all of the content in my UIScrollView, and not just what is currently visible? I suspect that I can't use UIGraphicsGetCurrentContext()
for a UIScrollView, but I don't know what to use instead, and the Apple docs on this aren't really very helpful.
If you have a subview taking the whole content size of the scrollView with the scrolling content you can do it like this:
CGContextRef context = UIGraphicsGetCurrentContext();
UIView *contentView = [scrollView subviews][0];
[contentView.layer renderInContext:context];
If there are multiple views in the scrollView you can do it like this:
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(
scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.contentSize.width,
scrollView.contentSize.height)];
for(UIView *view in [scrollView subviews]){
[contentView addSubview: view];
}
CGContextRef context = UIGraphicsGetCurrentContext();
[contentView.layer renderInContext:context];
Then you need to get the views back into the scrollView. Probably there is a way to copy them but I am not sure how. Anyhow here is what should work:
for(UIView *view in [contentView subviews]){
[view removeFromSuperView];
[scrollView addSubview:view];
}
You can set frame of UIScrollView equal to content size of it and content offset to 0 before calling renderInContext. After that revert frame to original.
myView.frame = CGRectMake(myView.frame.origin.x,myView.frame.origin.y,myView.contentSize.with,myView.contentSize.height);
This code i used to make pdf from uiscrollview and it does help but it will not be as good as if we draw on pdf -- please have look -- Pdf from UIScrollView
- (void) createPDF
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *directroyPath = nil;
directroyPath = [documentsDirectory stringByAppendingPathComponent:@"temp"];
NSString *filePath = [directroyPath stringByAppendingPathComponent:@"test.pdf"];
// check for the "PDF" directory
NSError *error;
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
} else {
[[NSFileManager defaultManager] createDirectoryAtPath:directroyPath
withIntermediateDirectories:NO
attributes:nil
error:&error];
}
CGContextRef pdfContext = [self createPDFContext:_scrollView2.bounds path:(CFStringRef)filePath];
NSLog(@"PDF Context created");
/*
Here limit of i is no of pages in your uiscrollview or
you can use hit and trial here because there is a
length of page is going to be equal to
the visible size of uiscrollView in your application
*/
for (int i = 0 ; i< 2 ; i++)
{
// page 1
CGContextBeginPage (pdfContext,nil);
//turn PDF upsidedown
CGAffineTransform transform = CGAffineTransformIdentity;
//here 365 is equal to the height of myScrollView.frame.size.height
transform = CGAffineTransformMakeTranslation(0, (i+1) * 365);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(pdfContext, transform);
//Draw view into PDF
[_scrollView2.layer renderInContext:pdfContext];
CGContextEndPage (pdfContext);
[_scrollView2 setContentOffset:CGPointMake(0, (i+1) * 365) animated:NO];
}
CGContextRelease (pdfContext);
}
- (CGContextRef) createPDFContext:(CGRect)inMediaBox path:(CFStringRef) path
{
CGContextRef myOutContext = NULL;
CFURLRef url;
url = CFURLCreateWithFileSystemPath (NULL, path,
kCFURLPOSIXPathStyle,
false);
if (url != NULL) {
myOutContext = CGPDFContextCreateWithURL (url,
&inMediaBox,
NULL);
CFRelease(url);
}
return myOutContext;
}
Check ScrollViewToPDF example and understand it.
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
Note : It captures all visible as well as invisible part of scrollView