web-dev-qa-db-fra.com

Capture d'écran dans Swift iOS?

Comment puis-je prendre une capture d'écran de mon écran par code (dans Swift) et l'enregistrer? Puis-je prendre une capture d'écran et l'enregistrer en tant qu'image?

J'ai regardé et j'ai vu ce code, mais je ne peux pas l'utiliser (je pense) car il ne fait rien.

var screen = UIScreen.mainScreen()
snapshotVieww = screen.snapshotViewAfterScreenUpdates(false)
UIGraphicsBeginImageContextWithOptions(screen.bounds.size, false, 0)
snapshotVieww.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
provino = UIImageView(image: image)
22
Giorgio Nocera

Avec Swift 4/iOS 10.3, vous pouvez choisir l’une des méthodes suivantes pour résoudre votre problème.


1. Prendre une capture d'écran de la vue d'un contrôleur de vue

Le code suivant montre comment prendre une capture d'écran et la sauvegarder dans l'album photo du périphérique: 

import UIKit

class ViewController: UIViewController {

    /* ... */

    @IBAction func screenshot(_ sender: UIBarButtonItem) {
        //Create the UIImage
        UIGraphicsBeginImageContextWithOptions(view.frame.size, true, 0)
        guard let context = UIGraphicsGetCurrentContext() else { return }
        view.layer.render(in: context)
        guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return }
        UIGraphicsEndImageContext()

        //Save it to the camera roll
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    }

}

Notez que le résultat de ce code sera une image .JPG. Notez également que la barre de navigation et la barre d'état n'apparaîtront pas dans l'image finale.

Depuis iOS 10, vous pouvez utiliser le code ci-dessous au lieu du code précédent:

import UIKit

class ViewController: UIViewController {

    /* ... */

    @IBAction func screenshot(_ sender: UIBarButtonItem) {
        //Create the UIImage
        let renderer = UIGraphicsImageRenderer(size: view.frame.size)
        let image = renderer.image(actions: { context in
            view.layer.render(in: context.cgContext)
        })

        //Save it to the camera roll
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    }

}

2. Prendre une capture d'écran d'une fenêtre iPhone

Si vous souhaitez prendre une capture d'écran incluant la barre de navigation (mais pas la barre d'état), vous pouvez utiliser le code suivant:

import UIKit

class ViewController: UIViewController {

    /* ... */

    @IBAction func screenshot(_ sender: UIBarButtonItem) {
        //Create the UIImage
        guard let layer = UIApplication.shared.keyWindow?.layer else { return }
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, true, 0)
        guard let context = UIGraphicsGetCurrentContext() else { return }
        layer.render(in: context)
        guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return }
        UIGraphicsEndImageContext()

        //Save it to the camera roll
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    }

}

Depuis iOS 10, vous pouvez utiliser le code ci-dessous au lieu du code précédent:

import UIKit

class ViewController: UIViewController {

    /* ... */

    @IBAction func screenshot(_ sender: UIBarButtonItem) {
        //Create the UIImage
        guard let layer = UIApplication.shared.keyWindow?.layer else { return }
        let renderer = UIGraphicsImageRenderer(size: layer.frame.size)
        let image = renderer.image(actions: { context in
            layer.render(in: context.cgContext)
        })

        //Save it to the camera roll
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    }

}

Rappel

Depuis iOS 10, pour éviter le blocage de votre application lorsque vous appelez votre méthode screenshot(_:), vous devez ajouter la clé NSPhotoLibraryUsageDescription au fichier Info.plist de votre projet:

<key>NSPhotoLibraryUsageDescription</key>
<string>Some description to explain why access is required</string>
39
Imanou Petit

Juste ces quelques lignes de code obtiendront le screenShot de la vue: (juste testé)

  UIGraphicsBeginImageContextWithOptions(UIScreen.mainScreen().bounds.size, false, 0);
  self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
  var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();

  UIGraphicsEndImageContext();

  self.imgView.image = image;
8
Kumar KL

// Une capture d'écran à partager sur Facebook ou sur Facebook, c'est comme ça ...

func shareButtonClickedToTwitter(){
UIGraphicsBeginImageContextWithOptions(CGSizeMake(320,320), false, 0)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
self.view?.drawViewHierarchyInRect(CGRectMake(-30, -30, self.frame.size.width, self.frame.size.height), afterScreenUpdates: true)
var screenShot  = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.vc.showTWShare("I scored \(score) in Beanystalk can you do better? Available in App Store..", shareImage: screenShot)}


func shareButtonClickedToFaceboook() {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(320,320), false, 0)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
self.view?.drawViewHierarchyInRect(CGRectMake(-30, -30, self.frame.size.width, self.frame.size.height), afterScreenUpdates: true)
var screenShot  = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.vc.showFbShare("I got \(score) Points whilst playing BeanyStalk! Can you beat me?..", shareImageF: screenShot)  }

// fonction pour le partage facebook.

    func showFbShare(messageFB: String , shareImageF: UIImage) {
  println(messageFB)
  if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook){
    var fbSheet = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
    fbSheet.completionHandler = {
      result in
      switch result {
      case SLComposeViewControllerResult.Cancelled:
        break
      case SLComposeViewControllerResult.Done:
        break
      }
    }
    fbSheet.addImage(shareImageF)
    fbSheet.setInitialText("\(messageFB) Click here to fun https://hereIsLink/")
    println(messageFB)
    self.presentViewController(fbSheet, animated: false, completion: {
    })
  }
  else {
    var alert = UIAlertController(title: "Accounts", message: "Please login to a facebook account to share.", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
    self.presentViewController(alert, animated: true, completion: nil)
  }
}

// fonction de partage Twitter

func showTWShare(message: String , shareImage: UIImage) {
println(message)
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter){
  var twSheet = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
  twSheet.completionHandler = {
    result in
    switch result {
    case SLComposeViewControllerResult.Cancelled:
      break
    case SLComposeViewControllerResult.Done:
      break
    }
  }
  twSheet.setInitialText("\(message) Click here 2 fun https://hereIsLink/") //The default text in the Tweet
  twSheet.addImage(shareImage)
  println(message)
  self.presentViewController(twSheet, animated: false, completion: {
  })
}
else {
  var alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to share.", preferredStyle: UIAlertControllerStyle.Alert)
  alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
  self.presentViewController(alert, animated: true, completion: nil)
} }
2
Rex

Pour prendre une capture d'écran, Imanou Petit répond très bien. J'ai traité les multiples versions d'iOS et de tvOS dans une seule extension et je les ai mises à disposition sous forme de module (pod 'SwiftImageEffects').

Code complet ci-dessous (de https://github.com/Coeur/ImageEffects/blob/master/SwiftImageEffects/ImageEffects%2Bextensions.Swift ):

extension UIView {
    /// Get a UIImage from the UIView
    /// - parameter opaque:
    /// A Boolean flag indicating whether the image is opaque. Specify true to ignore the alpha channel. Specify false to handle any partially transparent pixels.
    /// - parameter scale:
    /// The scale factor to apply to the image. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.
    open func renderImage(opaque: Bool = false, scale: CGFloat = 0) -> UIImage {
        if #available(iOS 10.0, tvOS 10.0, *) {
            let format = UIGraphicsImageRendererFormat.default()
            format.opaque = opaque
            format.scale = scale
            return UIGraphicsImageRenderer(size: bounds.size, format: format).image { layer.render(in: $0.cgContext) }
        } else {
            // Fallback on earlier versions
            // The following methods will only return a 8-bit per channel context in the DeviceRGB color space.
            // Any new bitmap drawing code is encouraged to use UIGraphicsImageRenderer in lieu of this API.
            UIGraphicsBeginImageContextWithOptions(bounds.size, opaque, scale)
            defer { UIGraphicsEndImageContext() }
            layer.render(in: UIGraphicsGetCurrentContext()!)
            return UIGraphicsGetImageFromCurrentImageContext()!
        }
    }
}

Ensuite, vous pouvez prendre une capture d'écran aussi simplement que:

func screenshot() {
    if let image = UIApplication.shared.keyWindow?.renderImage() {
        // saving will require a NSPhotoLibraryUsageDescription in your project's Info.plist
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    }
}
1
Cœur