Tim Sullivan Tim Sullivan - 1 month ago 10
iOS Question

Getting a screenshot of a UIScrollView, including offscreen parts

I have a UIScrollView decendent that implements a takeScreenshot method that looks like this:

-(void)takeScreenshot {
CGRect contextRect = CGRectMake(0, 0, 768, 1004);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();

// do something with the viewImage here.

This basically moves to the top of the scroll view, and takes a screenshot of the visible area. It works fine when the iPad is oriented portrait, but when it's in landscape the bottom of the image is cut off (as the height of the visible area is only 748, not 1004).

Is it possible to get a snapshot of the UIScrollView, including areas not on screen? Or do I need to scroll the view down, take a second photo and stitch them together?


Here is code that works ...

- (IBAction) renderScrollViewToImage
    UIImage* image = nil;

        CGPoint savedContentOffset = _scrollView.contentOffset;
        CGRect savedFrame = _scrollView.frame;

        _scrollView.contentOffset = CGPointZero;
        _scrollView.frame = CGRectMake(0, 0, _scrollView.contentSize.width, _scrollView.contentSize.height);

        [_scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];     
        image = UIGraphicsGetImageFromCurrentImageContext();

        _scrollView.contentOffset = savedContentOffset;
        _scrollView.frame = savedFrame;

    if (image != nil) {
        [UIImagePNGRepresentation(image) writeToFile: @"/tmp/test.png" atomically: YES];
        system("open /tmp/test.png");

The last few lines simply write the image to /tmp/test.png and then opens it in Preview.app. This obviously only works on in the Simulator :-)

Complete project in the ScrollViewScreenShot Github Repository