How to take a screeshot in iOS programmatically

In iOS we can press the HOME and the POWER button together at any time and a screenshot of what’s currently being displayed will be saved to the Camera Roll as if by magic. If we wanted to do the same thing programmatically it’s not that easy. It appears there’s no iOS system method that does this for us.

We have several options, let me describe two of those. I’ll add others if there are more convenient methods.

OPTION 1: using UIWindow

To make sure we screengrab everything in our display we can transfer the content of our top most UIWindow into a graphics context with the size of our screen. This will work no matter which class you use it in:

// create graphics context with screen size
CGRect screenRect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blackColor] set];
CGContextFillRect(ctx, screenRect);

// grab reference to our window
UIWindow *window = [UIApplication sharedApplication].keyWindow;

// transfer content into our context
[window.layer renderInContext:ctx];
UIImage *screengrab = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

The advantage with this method is that even popovers and alert views are added to the resulting UIImage.

OPTION 2: using UIView

If we only need to turn a UIView into a UIImage then the next method will work fine. The disadvantage is that certain types of views (such as OpenGL and popovers) will not be captured. In addition, you need a reference to the UIView you’d like to capture. In this example I’m using my Master/Detail App’s split view controller:

// grab reference to the view you'd like to capture
UIView *wholeScreen = self.splitViewController.view;

// define the size and grab a UIImage from it
UIGraphicsBeginImageContextWithOptions(wholeScreen.bounds.size, wholeScreen.opaque, 0.0);
[wholeScreen.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screengrab = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Saving a UIImage to Camera Roll

The result of both methods above is a UIImage you can do with as you please. Let’s save it to the Camera Roll for now:

// save screengrab to Camera Roll
UIImageWriteToSavedPhotosAlbum(screengrab, nil, nil, nil);

One thing of note:
If you call either method above via a standard button, the screenshot is taken during the button animation (half faded for example).

Further Reading





One thought on “How to take a screeshot in iOS programmatically

Leave a Reply