Question

i'm trying to save a screenshot of an entire UIWebView. BUT: if the web page is very long, with a lot of javascript or dynamic objects and if i don't manually (and patiently!) scroll all the page, the webview never loads some areas that stay gray and unloaded forever. How do I load THE WHOLE web page? Or is it a different problem? Nothing on the Internet helped me. Thank you.

update:

Here's what i'm currently doing in a "PrintButton" IBAction:

// save old frame of webView
    CGPoint savedContentOffset =    _webPage.scrollView.contentOffset;
    CGRect  savedFrame =            _webPage.scrollView.frame;

    CGSize  webPageSize =    CGSizeMake(_webPage.scrollView.contentSize.width, _webPage.scrollView.contentSize.height);
    CGRect  stringRect =     CGRectMake(0, 0, webPageSize.width, webPageSize.height);


    // set new frame
    _webPage.scrollView.contentOffset = CGPointZero;
    _webPage.scrollView.frame = stringRect;


    UIGraphicsBeginImageContextWithOptions(webPageSize,NO,1.0);


    [_webPage.scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
    self.viewImage = UIGraphicsGetImageFromCurrentImageContext();

    // re-set old frame
    _webPage.scrollView.contentOffset = savedContentOffset;
    _webPage.scrollView.frame = savedFrame;

    UIGraphicsEndImageContext();

    // save in gallery
    UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);

The code works: an image is saved in my photo gallery. But as said, if the web page is very complex, long, heavy, I don't know what, empty areas (I said gray because the background of the webview is gray) will appear. Usually, if I don't scroll the page before pressing the print button, 95% of the page that I didn't scroll is empty, gray.

Was it helpful?

Solution

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];
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top