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条回答
一夜七次
2楼-- · 2019-01-03 13:30

Swift 3 Extension for UIWindow

public extension UIWindow {

  func capture() -> UIImage? {

    UIGraphicsBeginImageContextWithOptions(self.frame.size, self.isOpaque, UIScreen.main.scale)
    self.layer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image

  }
}]
查看更多
一夜七次
3楼-- · 2019-01-03 13:31

The recommended way to create a context in iOS 10 is to use UIGraphicsImageRenderer.

extension UIView {
    func capture() -> UIImage? {
        var image: UIImage?

        if #available(iOS 10.0, *) {
            let format = UIGraphicsImageRendererFormat()
            format.opaque = isOpaque
            let renderer = UIGraphicsImageRenderer(size: frame.size, format: format)
            image = renderer.image { context in
                drawHierarchy(in: frame, afterScreenUpdates: true)
            }
        } else {
            UIGraphicsBeginImageContextWithOptions(frame.size, isOpaque, UIScreen.main.scale)
            drawHierarchy(in: frame, afterScreenUpdates: true)
            image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
        }

        return image
    }
}
查看更多
孤傲高冷的网名
4楼-- · 2019-01-03 13:33

view.snapshotView(afterScreenUpdates: true)

查看更多
We Are One
5楼-- · 2019-01-03 13:34

This is similar, hopefully it helps someone in the future.

self.view.image() //returns UIImage

Here's a Swift 3 solution

https://gist.github.com/nitrag/b3117a4b6b8e89fdbc12b98029cf98f8

查看更多
手持菜刀,她持情操
6楼-- · 2019-01-03 13:35

For ease I would add an extension in it's own file

import UIKit

  public extension UIWindow {

    func capture() -> UIImage {

      UIGraphicsBeginImageContextWithOptions(self.frame.size, self.opaque, UIScreen.mainScreen().scale)
      self.layer.renderInContext(UIGraphicsGetCurrentContext()!)
      let image = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()

      return image
  }
}

call the extension as follows...

let window: UIWindow! = UIApplication.sharedApplication().keyWindow

let windowImage = window.capture()

Similarly, one could extended UIView to capture an image of that....

查看更多
走好不送
7楼-- · 2019-01-03 13:37

Details

Xcode 9.3, Swift 4.1

Tested on iOS: 9, 10, 11

Solution

import UIKit

extension UIApplication {

    var screenShot: UIImage?  {
        return keyWindow?.layer.screenShot
    }
}

extension CALayer {

    var screenShot: UIImage?  {
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
        if let context = UIGraphicsGetCurrentContext() {
            render(in: context)
            let screenshot = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return screenshot
        }
        return nil
    }
}

Usage

 imageView.image = UIApplication.shared.screenShot

Details

Xcode 8.2.1, swift 3

Version 1 for iOS 10x

import UIKit

extension UIApplication {

    var screenShot: UIImage?  {

        if let layer = keyWindow?.layer {
            let scale = UIScreen.main.scale

            UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
            if let context = UIGraphicsGetCurrentContext() {
                layer.render(in: context)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
        }
        return nil
    }
}

Version 2 for iOS 9x, 10x

If you will try to use Version 1 code in iOS 9x you will have error: CGImageCreateWithImageProvider: invalid image provider: NULL.

import UIKit

extension UIApplication {

    var screenShot: UIImage?  {

        if let rootViewController = keyWindow?.rootViewController {
            let scale = UIScreen.main.scale
            let bounds = rootViewController.view.bounds
            UIGraphicsBeginImageContextWithOptions(bounds.size, false, scale);
            if let _ = UIGraphicsGetCurrentContext() {
                rootViewController.view.drawHierarchy(in: bounds, afterScreenUpdates: true)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
        }
        return nil
    }
}

Usage

let screenShot = UIApplication.shared.screenShot!
查看更多
登录 后发表回答