I have tried several variations of solving this, and found 2 key changes that seem to make it work better.
First, I run renderInContext
on _webView
not on _webView.scrollView
. The other is that I adjust the offset of the content by calling scrollRectToVisible:animated:
instead of setting contentOffset
manually.
See sample code that grabs a sequence of images and saves them to camera roll. With a few modifications you could output the images into a single tall view instead and save it as a single continuous image.
Note that this assumes the web page only needs to be scrolled vertically, not horizontally.
- (void) printScreen {
// this is a method that starts the screenshot taking process
// this line is necessary to capture the completion of the scrollView animation
_webView.scrollView.delegate = self;
// save the first image
UIGraphicsBeginImageContextWithOptions(_webView.bounds.size, NO, 0);
[_webView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
// scroll to the next section
[_webView.scrollView scrollRectToVisible:CGRectMake(0, _webView.frame.size.height, _webView.frame.size.width, _webView.frame.size.height) animated:YES];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
// at this point the webView scrolled to the next section
// I save the offset to make the code a little easier to read
CGFloat offset = _webView.scrollView.contentOffset.y;
UIGraphicsBeginImageContextWithOptions(_webView.bounds.size, NO, 0);
// note that the below line will not work if you replace _webView.layer with _webView.scrollView.layer
[_webView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
// if we are not done yet, scroll to next section
if (offset < _webView.scrollView.contentSize.height) {
[_webView.scrollView scrollRectToVisible:CGRectMake(0, _webView.frame.size.height+offset, _webView.frame.size.width, _webView.frame.size.height) animated:YES];
}
}