Capture iPhone screen with status bar included?

2019-01-18 15:04发布

问题:

I am looking for a way to capture a screenshot on the iPhone with the top status bar included, I am currently using the following code:

    UIGraphicsBeginImageContext(self.view.bounds.size); //self.view.window.frame.size
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);

The above code sucessfully takes a screenshot of the iPhone UIView but does not include the top status bar (In its place is just a blank 20px space).

回答1:

As of iOS 7, you can do this without the use of private APIs using

UIView *screenshotView = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];

See my answer to this question:

Moving status bar in iOS 7



回答2:

You can get the entire contents of the screen by calling the private API UIGetScreenImage. See my previous answer to a similar question for details.



回答3:

As of Oct 8, 2009, the use of UIGetScreenImage got my app rejected! :( I would not advise using it. I believe Apple is trying to clean up all the apps and make them conform to the new 3.x OS/APIs. I'm looking for an alternative. If anyone has any suggestions. The video API?



回答4:

Instead of using private API, why not render the entire UIWindow into the image context? It might be enough to replace self.view with self.view.window in your code.

You can also get the current window(s) as a property of the [UIApplication sharedApplication] instance. It's possible the status bar is on a separate window layer and maybe you'll have to render the windows in order.

Something like this:

UIGraphicsBeginImageContext(self.view.window.frame.size);
for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
   [window.layer renderInContext:UIGraphicsGetCurrentContext()];
}
UIImage *screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);

At any rate, you probably don't need to resort to private API.