ios - tomar - ¿Cómo tomo una captura de pantalla de pantalla completa en Swift?
cómo hacer una captura de pantalla en iphone 5 (11)
view.snapshotView (afterScreenUpdates: true)
Encontré este código :
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)
}
¿Qué debo hacer para incluir todos los demás elementos, como la barra de navegación, en las capturas de pantalla?
Detalles
Xcode 9.3, Swift 4.1
Probado en iOS: 9, 10, 11
Solución
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
}
}
Uso
imageView.image = UIApplication.shared.screenShot
Detalles
Xcode 8.2.1, veloz 3
Versión 1 para 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
}
}
Versión 2 para iOS 9x, 10x
Si intenta usar el código de la Versión 1 en iOS 9x , tendrá un error: CGImageCreateWithImageProvider: proveedor de imágenes no válido: 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
}
}
Uso
let screenShot = UIApplication.shared.screenShot!
Ejemplo de 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
}
En lugar de solo arrojar la respuesta, permítame explicarle qué hace su código actual y cómo modificarlo para capturar la pantalla completa.
UIGraphicsBeginImageContext(view.frame.size)
Esta línea de código crea un nuevo contexto de imagen con el mismo tamaño que la view
. Lo más importante es que el nuevo contexto de imagen tiene el mismo tamaño que la view
. A menos que desee capturar una versión de baja resolución (no retina) de su aplicación, probablemente debería usar UIGraphicsBeginImageContextWithOptions
en UIGraphicsBeginImageContextWithOptions
lugar. Luego puede pasar 0.0
para obtener el mismo factor de escala que la pantalla principal de los dispositivos.
view.layer.renderInContext(UIGraphicsGetCurrentContext())
Esta línea de código representará la capa de la vista en el contexto de gráficos actual (que es el contexto que acaba de crear). Lo principal que debemos quitar aquí es que solo la view
(y sus subvistas) se dibujan en el contexto de la imagen.
let image = UIGraphicsGetImageFromCurrentImageContext()
Esta línea de código crea un objeto UIImage a partir de lo que se ha dibujado en el contexto gráfico.
UIGraphicsEndImageContext()
Esta línea de código finaliza el contexto de la imagen. Es limpieza (usted creó el contexto y debería eliminarlo también).
El resultado es una imagen del mismo tamaño que la view
, con la view
y sus subvistas dibujadas en ella.
Si desea dibujar todo en la imagen, debe crear una imagen del tamaño de la pantalla y dibujar en ella todo lo que está en la pantalla. En la práctica, es probable que solo hable de todo en la "ventana clave" de su aplicación. Como UIWindow
es una subclase de UIView
, también se puede dibujar en un contexto de imagen.
Esto es similar, con suerte, ayuda a alguien en el futuro.
self.view.image() //returns UIImage
Aquí hay una solución de Swift 3
https://gist.github.com/nitrag/b3117a4b6b8e89fdbc12b98029cf98f8
La forma recomendada de crear un contexto en iOS 10 es usar 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
}
}
Para mayor facilidad, agregaría una extensión en su propio archivo
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
}
}
llama a la extensión de la siguiente manera ...
let window: UIWindow! = UIApplication.sharedApplication().keyWindow
let windowImage = window.capture()
Del mismo modo, uno podría extender UIView para capturar una imagen de eso ....
Yo uso este método:
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;
}
Captura todas las barras excepto la de estado, y no solicita permiso para guardar imágenes en el rollo de la cámara.
¡Espero eso ayude!
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
}
Actualizado para Swift 2
El código que proporciona funciona pero no le permite capturar NavigationBar
y StatusBar
en su captura de pantalla. Si desea tomar una captura de pantalla de su dispositivo que incluirá NavigationBar
, debe usar el siguiente código:
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)
}
Con este código:
- La primera vez que inicie la aplicación y llame a este método, el dispositivo iOS le pedirá permiso para guardar su imagen en el rollo de la cámara.
- El resultado de este código será una imagen .JPG.
-
StatusBar
no aparecerá en la imagen final.
Swift 3 Extension para 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
}
}]
// 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
}