How do I take a full screen Screenshot in Swift?

2019-01-03 12:55发布

I've found this code:

func screenShotMethod() {
    //Create the UIImage
    UIGraphicsBeginImageContext(view.frame.size)
    view.layer.renderInContext(UIGraphicsGetCurrentContext())
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    //Save it to the camera roll
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}

What do I need to do to get all the other elements, like the navigation bar, into the screenshots?

12条回答
Deceive 欺骗
2楼-- · 2019-01-03 13:13

I use this method:

func captureScreen() -> UIImage {
    var window: UIWindow? = UIApplication.sharedApplication().keyWindow
    window = UIApplication.sharedApplication().windows[0] as? UIWindow
    UIGraphicsBeginImageContextWithOptions(window!.frame.size, window!.opaque, 0.0)
    window!.layer.renderInContext(UIGraphicsGetCurrentContext())
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image;
}

It captures all but the status bar, and it doesn't ask for permission to save images in the camera roll.

Hope it helps!

查看更多
可以哭但决不认输i
3楼-- · 2019-01-03 13:14

Swift 3 example:

func captureScreen() -> UIImage? {
    guard let context = UIGraphicsGetCurrentContext() else { return .none }
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
    view.layer.render(in: context)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}
查看更多
孤傲高冷的网名
4楼-- · 2019-01-03 13:16
  // Full Screen Shot function. Hope this will work well in swift.
  func screenShot() -> UIImage {                                                    
    UIGraphicsBeginImageContext(CGSizeMake(frame.size.width, frame.size.height))
    var context:CGContextRef  = UIGraphicsGetCurrentContext()
    self.view?.drawViewHierarchyInRect(frame, afterScreenUpdates: true)
    var screenShot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext();  
    return screenShot
  }
查看更多
贪生不怕死
5楼-- · 2019-01-03 13:21

My version also capture a keyboard. Swift 4.2

extension UIApplication {

    var screenshot: UIImage? {
        UIGraphicsBeginImageContextWithOptions(UIScreen.main.bounds.size, false, 0)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        for window in windows {
            window.layer.render(in: context)
        }
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }

}
查看更多
何必那么认真
6楼-- · 2019-01-03 13:23

Instead of just throwing the answer out there, let me explain what your current code does and how to modify it to capture the full screen.

UIGraphicsBeginImageContext(view.frame.size)

This line of code creates a new image context with the same size as view. The main thing to take away here is that the new image context is the same size as view. Unless you want to capture a low resolution (non-retina) version of your application, you should probably be using UIGraphicsBeginImageContextWithOptions instead. Then you can pass 0.0 to get the same scale factor as the devices main screen.

view.layer.renderInContext(UIGraphicsGetCurrentContext())

This line of code will render the view's layer into the current graphics context (which is the context you just created). The main thing to take away here is that only view (and its subviews) are being drawn into the image context.

let image = UIGraphicsGetImageFromCurrentImageContext()

This line of code creates an UIImage object from what has been drawn into the graphics context.

UIGraphicsEndImageContext()

This line of code ends the image context. It's clean up (you created the context and should remove it as well.


The result is an image that is the same size as view, with view and its subviews drawn into it.

If you want to draw everything into the image, then you should create an image that is the size of the screen and draw everything that is on screen into it. In practice, you are likely just talking about everything in the "key window" of your application. Since UIWindow is a subclass of UIView, it can be drawn into a image context as well.

查看更多
Melony?
7楼-- · 2019-01-03 13:24

Swift 4

    /// Takes the screenshot of the screen and returns the corresponding image
    ///
    /// - Parameter shouldSave: Boolean flag asking if the image needs to be saved to user's photo library. Default set to 'true'
    /// - Returns: (Optional)image captured as a screenshot
    open func takeScreenshot(_ shouldSave: Bool = true) -> UIImage? {
        var screenshotImage :UIImage?
        let layer = UIApplication.shared.keyWindow!.layer
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
        guard let context = UIGraphicsGetCurrentContext() else {return nil}
        layer.render(in:context)
        screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        if let image = screenshotImage, shouldSave {
            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
        }
        return screenshotImage
    }

Updated for Swift 2

The code you provide works but doesn't allow you to capture the NavigationBar and the StatusBar in your screenshot. If you want to take a screenshot of your device that will include the NavigationBar, you have to use the following code:

func screenShotMethod() {
    let layer = UIApplication.sharedApplication().keyWindow!.layer
    let scale = UIScreen.mainScreen().scale
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

    layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
}

With this code:

  • The first time you launch the app and call this method, the iOS device will ask you the permission to save your image in the camera roll.
  • The result of this code will be a .JPG image.
  • The StatusBar will not appear in the final image.
查看更多
登录 后发表回答