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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With