Reputation: 1219
I need to capture a UIView and all it's subviews into a UIImage. The problem is that part of the view is off screen, so I can't use the screen capture function, and when I try to use the UIGraphicsGetImageFromCurrentImageContext() function, it doesn't seem to capture the subviews as well. Should it be capturing the subviews and I'm just doing something wrong? If not, is there any other way of accomplishing this?
Upvotes: 16
Views: 10918
Reputation: 3926
func getImage(from view:UIView) -> UIImage? {
defer { UIGraphicsEndImageContext() }
UIGraphicsBeginImageContextWithOptions(view.frame.size, true, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
view.layer.render(in: context)
return UIGraphicsGetImageFromCurrentImageContext()
}
Upvotes: 2
Reputation: 34523
Here's a Swift 2.x version that should work if you first create an array of the UIViews to get flattened:
// Flattens <allViews> into single UIImage
func flattenViews(allViews: [UIView]) -> UIImage? {
// Return nil if <allViews> empty
if (allViews.isEmpty) {
return nil
}
// If here, compose image out of views in <allViews>
// Create graphics context
UIGraphicsBeginImageContextWithOptions(UIScreen.mainScreen().bounds.size, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()
CGContextSetInterpolationQuality(context, CGInterpolationQuality.High)
// Draw each view into context
for curView in allViews {
curView.drawViewHierarchyInRect(curView.frame, afterScreenUpdates: false)
}
// Extract image & end context
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// Return image
return image
}
Upvotes: 0
Reputation: 6118
That's the right way to go:
+ (UIImage *) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
This method is an extension method for UIImage class, and it will also take care of making the image looks good on any future high-resolution devices.
Upvotes: 29
Reputation: 33592
Do you mean
UIGraphicsBeginImageContext(view.bounds.size);
[view.layer drawInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
doesn't work? I'm pretty sure it ought to...
Upvotes: 2