Wie kann ich Screenshots nach Code (in Swift) von meinem Bildschirm aufnehmen und speichern?
Ich habe nachgeschaut und sehe diesen Code, aber ich kann ihn nicht verwenden (denke ich), weil er nichts tut.
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)
Mit Swift 4/iOS 10.3 können Sie eine der folgenden Möglichkeiten wählen, um Ihr Problem zu lösen.
Der folgende Code zeigt, wie ein Screenshot erstellt und im Geräte-Fotoalbum gespeichert wird:
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)
}
}
Beachten Sie, dass das Ergebnis dieses Codes ein JPG-Bild ist. Beachten Sie auch, dass die Navigationsleiste und die Statusleiste nicht im endgültigen Bild angezeigt werden.
Seit iOS 10 können Sie als Alternative zum vorherigen Code den folgenden Code verwenden:
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)
}
}
Wenn Sie einen Screenshot erstellen möchten, der die Navigationsleiste enthält (jedoch nicht die Statusleiste), können Sie den folgenden Code verwenden:
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)
}
}
Seit iOS 10 können Sie als Alternative zum vorherigen Code den folgenden Code verwenden:
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)
}
}
Um zu verhindern, dass Ihre App beim Aufruf Ihrer screenshot(_:)
-Methode abstürzt, müssen Sie seit iOS 10 den Schlüssel NSPhotoLibraryUsageDescription
zur Info.plist-Datei Ihres Projekts hinzufügen:
<key>NSPhotoLibraryUsageDescription</key>
<string>Some description to explain why access is required</string>
Nur diese wenigen Codezeilen erhalten den screenShot der Ansicht: (nur getestet)
UIGraphicsBeginImageContextWithOptions(UIScreen.mainScreen().bounds.size, false, 0);
self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.imgView.image = image;
// Screenshot im Facebook oder auf Twitter ist so ...
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) }
// Funktion für Facebook-Share.
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)
}
}
// Twitter Share-Funktion
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)
} }
Um einen Screenshot zu machen, ist die Antwort von Imanou Petit sehr gut. Ich habe die verschiedenen Versionen von iOS und tvOS in einer einzigen Erweiterung behandelt und als Pod (pod 'SwiftImageEffects'
) zur Verfügung gestellt.
Voller Code (von 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()!
}
}
}
Dann können Sie einen Screenshot so einfach machen wie:
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)
}
}