Reputation: 1074
I use this method for taking a snapshot:
UIView *snapshotView = [someView snapshotAfterScreenUpdates:NO];
This gives me a UIView that I can play with.
But, I need the UIImage of it and not the UIView.
This is the method I use for converting a UIView to an UIImage:
- (UIImage *)snapshotOfView:(UIView *)view
{
UIImage *snapshot;
UIGraphicsBeginImageContext(view.frame.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
It doesn't work, the snapshot is a blank UIImage because the snapshotView isn't rendered.
The obvious thing to do is to directly take a snapshot of the view instead of taking the snapshot in the form of a UIView and then converting it.
The problem with the obvious method is that I'm using a WKWebView that has a huge bug that doesn't allow you to take screenshots. And that's true, I even reported the bug and they said they are trying to fix it.
So, how can I take the snapshot (UIImage) of the snapshotView without rendering it?
Upvotes: 9
Views: 9723
Reputation: 12953
Since accepter answer didn't worked for me (UIGraphicsGetImageFromCurrentImageContext()
returned nil
all the time) I found different solution for iOS10+:
let renderer = UIGraphicsImageRenderer(size: view.bounds.size)
let image = renderer.image { _ in view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) }
P.S. You may want to call updateConstraintsIfNeeded()
and layoutIfNeeded()
before rendering
Upvotes: 9
Reputation: 31745
drawViewHierarchyInRect
will work for you. You can use this directly on your WKWebView.
There is some useful detail on this Apple Technical Q&A. Also I touch on it here in answer to a slightly different question.
I use it in a category on UIView:
@implementation UIView (ImageSnapshot)
- (UIImage*)imageSnapshot {
UIGraphicsBeginImageContextWithOptions(self.bounds.size,
YES, self.contentScaleFactor);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end
I don't know what you mean by 'the obvious method' - but I have tested this on a WKWebView and it works.
Upvotes: 11