How Do I Take a Screen Shot of a UIView?

Viewed 104888

I am wondering how my iPhone app can take a screen shot of a specific UIView as a UIImage.

I tried this code but all I get is a blank image.

UIGraphicsBeginImageContext(CGSizeMake(320,480));
CGContextRef context = UIGraphicsGetCurrentContext();
[myUIView.layer drawInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

myUIView has dimensions 320x480 an it has some sub-views. What is the correct way to do this?

16 Answers

I think you may want renderInContext, not drawInContext. drawInContext is more a method you would override...

Note that it may not work in all views, specifically a year or so ago when I tried to use this with the live camera view it did not work.

There is new API from iOS 10

extension UIView {
    func makeScreenshot() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
        return renderer.image { (context) in
            self.layer.render(in: context.cgContext)
        }
    }
}
- (void)drawRect:(CGRect)rect {
  UIGraphicsBeginImageContext(self.bounds.size);    
  [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);  
}

This method may put in your Controller class.

CGImageRef UIGetScreenImage();

Apple now allows us to use it in a public application, even though it's a private API

Swift 4 updated :

extension UIView {
   var screenShot: UIImage?  {
        if #available(iOS 10, *) {
            let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
            return renderer.image { (context) in
                self.layer.render(in: context.cgContext)
            }
        } else {
            UIGraphicsBeginImageContextWithOptions(bounds.size, false, 5);
            if let _ = UIGraphicsGetCurrentContext() {
                drawHierarchy(in: bounds, afterScreenUpdates: true)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
            return nil
        }
    }
}
 // MARK: - Actions
 @objc func imageWasSaved(_ image: UIImage, error: Error?, context: UnsafeMutableRawPointer) {
     if let error = error {
         print(error.localizedDescription)
         return
     }

     print("Image was saved in the photo gallery")
     UIApplication.shared.open(URL(string:"photos-redirect://")!)
 }
   
 func takeScreenshot(of view: UIView) {
     
     let bounds = UIScreen.main.bounds
     UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)

     self.view.drawHierarchy(in: self.view.bounds, afterScreenUpdates: true)

        let screenshot = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
     UIImageWriteToSavedPhotosAlbum(screenshot, self, #selector(imageWasSaved), nil)
 }
   
Related