Snapshotting can be used on iOS to draw a view into an image, like a screenshot. Doing so is very beneficial in some scenarios such as smooth interface rotations and advanced animations.
Creating a snapshot is done via a CGContext with the following code:
// Begin the image context UIGraphicsBeginImageContextWithOptions(view.frame.size, // same size as our view NO, // transparent background (!opaque) 0); // screen scale, 0 = main screen scale CGContextRef ctx = UIGraphicsGetCurrentContext(); // Translate to our active region, for example, where the content currently is in a scroll view CGContextTranslateCTM(ctx, -view.bounds.origin.x, -view.bounds.origin.y); // Draw the view's layer [view.layer renderInContext:ctx]; // Grab the image UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); // End the image context (and clean up) UIGraphicsEndImageContext();
Easy enough. Typically this should only be done on the main thread; if the main thread is drawing your views to the screen and one of your threads is drawing views to an image there could be some clashes. Having said this, I have found it safe to do this on a thread under the condition that it is done before the run loop ends (but test this thoroughly). For example if you needed to make a lot of these snapshots, you could spawn X threads and draw them asynchronously and then halt the main thread until all the drawing was finished. Note that if you ever do drawing on a thread, instead of using UIGraphicsGetCurrentContext you must create your own context.
In iOS7 this got even easier. There were 3 methods added to the UIView interface that will create snapshots faster than the older renderInContext: method.
If you simply want to visually create a copy then show the copy on screen, you can spawn a ‘replica’ static snapshot view, and set it’s frame and add it as a subview as you would any other view. This is done with the snapshotViewAfterScreenUpdates: method.
UIView* viewToCopy = ...; UIView* snapshotView = [viewToCopy snapshotViewAfterScreenUpdates:YES]; [self.view addSubview:snapshotView];
There’s a similar method which instead creates a resizable snapshot, via resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets:.
If you need a UIImage version like in the above CGContextRef example, simply replace the [view.layer renderInContext:ctx]; line with the following:
// Draw the view's layer [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
So with this knowledge and a bit of work, you can create animations such as the springboard split folder animation: