如何在Swift中进行全屏幕截图?

我发现这个代码 :

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) } 

我需要做什么才能将所有其他元素(如导航栏)放到屏幕截图中?

让我解释一下你当前的代码是做什么的,以及如何修改它来捕捉整个屏幕。

 UIGraphicsBeginImageContext(view.frame.size) 

这行代码创build一个与view大小相同的新图像上下文。 这里带走的主要原因是新的图像上下文view大小相同 。 除非要捕获应用程序的低分辨率(非视网膜)版本,否则应该使用UIGraphicsBeginImageContextWithOptions 。 然后你可以通过0.0来获得与设备主屏幕相同的比例因子。

 view.layer.renderInContext(UIGraphicsGetCurrentContext()) 

这行代码将把视图的图层渲染到当前的graphics上下文中(这是你刚创build的上下文)。 这里最主要的一点是,只有view (及其子视图)才被吸引到图像上下文中。

 let image = UIGraphicsGetImageFromCurrentImageContext() 

这一行代码根据已经绘制到graphics上下文中的内容创build一个UIImage对象。

 UIGraphicsEndImageContext() 

这一行代码结束了图像上下文。 这是清理(你创build的上下文,并应该删除它。


结果是与view大小相同的图像,并将view及其子视图绘制到其中。

如果要将所有内容都绘制到图像中,则应该创build一个与屏幕大小相同的图像,并将屏幕上的所有内容绘制到该图像中。 实际上,您可能只是在应用程序的“关键窗口”中讨论所有内容。 由于UIWindowUIView的子类,它也可以被绘制到图像上下文中。

更新了Swift 2

您提供的代码有效,但不允许您在屏幕截图中捕获NavigationBarStatusBar 。 如果您想截取包含NavigationBar设备屏幕截图,则必须使用以下代码:

 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) } 

有了这个代码:

  • 第一次启动应用程序并调用此方法时,iOS设备将询问您是否有权将相机保存在相机胶卷中。
  • 这段代码的结果将是一个.JPG图像。
  • StatusBar不会出现在最终的图像。

Swift 3例子:

 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 } 

版本1为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 } } 

版本2为iOS 9x,10x

如果您尝试在iOS 9x中使用版本1代码,则会出现以下错误: 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 } } 

用法

 let screenShot = UIApplication.shared.screenShot! 

细节

xCode 8.2.1,swift 3

为了方便起见,我会在它自己的文件中添加一个扩展名

 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 } } 

调用扩展名如下…

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

同样,可以扩展UIView来捕捉这个图像….

在iOS 10中创build上下文的推荐方法是使用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 } } 

我用这个方法:

 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; } 

它捕获除状态栏以外的所有内容,并且不要求在相机胶卷中保存图像的权限。

希望它有帮助!

  // 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 } 

view.snapshotView(afterScreenUpdates:true)

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 } }] 

这是相似的,希望它可以帮助未来的人。

 self.view.image() //returns UIImage 

这是一个Swift 3解决scheme

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