I am attemting to transition from one UIView to another, when the user rotates the device. This, in of itself, is not difficult. However, since I am displaying completely di
- (UIImage *)captureView:(UIView *)view {
CGRect screenRect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(screenRect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor blackColor] set];
CGContextFillRect(ctx, screenRect);
[view.layer renderInContext:ctx];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Found this here :
http://discussions.apple.com/thread.jspa?messageID=8358740
This code worked for me
- (UIImage *)captureScreenInRect:(CGRect)captureFrame {
CALayer *layer;
layer = self.view.layer;
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenImage;
}
On Mac this is so easy... you just need -bitmapImageRepForCachingDisplayInRect:
, but of course iPhone has no such thing.
I think I would attack this by setting up a graphics context and calling [window drawRect:...]
on it to capture the current image of the screen. This is a bit out of spec, because you're not really supposed to go calling -drawRect:
yourself. I'd be a bit nervous of side-effects on doing this, but it may be fine. If it's a full-screen view you control, you could of course hoist the drawing code out of -drawRect:
so you're not calling that directly.
A similar approach would be to use CALayer -drawInContext:
of the current -presentationLayer
. That might be slightly more "in spec" since it's legal to pass that your own context. But I don't know if you'd actually be able to get all the sub-views correctly. Might depend on the nature of your UIWindow.
Anyway, great question. Maybe someone has a more clever solution, but this is the way I'd attack it.
EDIT: Thanks to Rob Terrell, and his clever UIApplication+TVOut.m, I was introduced to the private method UIGetScreenImage() which returns a CGImageRef. If you're willing to go to private methods, that's a nice option for you. Given its name and functionality, it looks pretty stable to me and seems unlikely to violate Apple's intent. I also bumped into a pretty nice discussion on Air Source. Read through the comments for several links.
I can guarantee you [window drawRect:] won't work. Most views don't implement drawRect: and it's certainly not recursive like on the mac.
drawInContext: is also pretty much hosed simalarly, as it's fundamentally asking the layer to draw itself, not its sublayers recursively. "Default implementation does nothing." says it all.
I implementing this for the Clif Bar Save Our Snow app in the app store by doing the following:
Yes, a rather large pain in the ass. But yes, it works pretty well and got through by Apple :).