Search code examples
iosswiftuiviewscreenshot

How to convert a UIView to an image


I want to convert a UIView to an image and save it in my app. Can someone please tell me how to take screenshot of a view or convert it to an image and what is the best way to save it in an app (Not camera roll)? Here is the code for the view:

var overView   = UIView(frame: CGRectMake(0, 0, self.view.frame.width/1.3, self.view.frame.height/1.3))
overView.center = CGPointMake(CGRectGetMidX(self.view.bounds),
CGRectGetMidY(self.view.bounds)-self.view.frame.height/16);
overView.backgroundColor = UIColor.whiteColor()
self.view.addSubview(overView)
self.view.bringSubviewToFront(overView)

Solution

  • An extension on UIView should do the trick.

    extension UIView {
    
        // Using a function since `var image` might conflict with an existing variable
        // (like on `UIImageView`)
        func asImage() -> UIImage {
            let renderer = UIGraphicsImageRenderer(bounds: bounds)
            return renderer.image { rendererContext in
                layer.render(in: rendererContext.cgContext)
            }
        }
    }
    

    Apple discourages using UIGraphicsBeginImageContext starting iOS 10 with the introduction of the P3 color gamut. UIGraphicsBeginImageContext is sRGB and 32-bit only. They introduced the new UIGraphicsImageRenderer API that is fully color managed, block-based, has subclasses for PDFs and images, and automatically manages the context lifetime. Check out WWDC16 session 205 for more details (image rendering begins around the 11:50 mark)

    To be sure that it works on every device, use #available with a fallback to earlier versions of iOS:

    extension UIView {
    
        // Using a function since `var image` might conflict with an existing variable
        // (like on `UIImageView`)
        func asImage() -> UIImage {
            if #available(iOS 10.0, *) {
                let renderer = UIGraphicsImageRenderer(bounds: bounds)
                return renderer.image { rendererContext in
                    layer.render(in: rendererContext.cgContext)
                }
            } else {
                UIGraphicsBeginImageContext(self.frame.size)
                self.layer.render(in:UIGraphicsGetCurrentContext()!)
                let image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return UIImage(cgImage: image!.cgImage!)
            }
        }
    }