使用completionSelector和completionTarget与UIImageWriteToSavedPhotosAlbum

时间:2015-04-07 21:19:36

标签: ios swift uiimage screenshot alert

我试图想办法让我的iOS应用程序将屏幕截图保存到相机胶卷,然后弹出警告,告诉用户屏幕截图已成功保存。

我能想到的唯一方法是使用某种形式的if / else循环(正如您在下面的伪代码注释中看到的那样),但我无法想到任何语法使用UIKit的UIImageWriteToSavedPhotosAlbum功能。我在Apple的开发网站上遇到了使用completionSelector和completionTarget的建议,但我并不真正了解如何使用它们或我应该使用哪些特定用语{{1}和我的代码中的completionSelector。我对Swift来说比较新。

有人可以解释一下它们是如何工作的,以及如何找到在我的代码中使用它们的语法?

completionTarget

5 个答案:

答案 0 :(得分:16)

import UIKit

class ViewController: UIViewController {

   @IBAction func buttonPressed(sender: AnyObject) {
      presentImagePickerController()
   }

}

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

   func presentImagePickerController() {
      let imagePickerController = UIImagePickerController()
      imagePickerController.delegate = self
      imagePickerController.sourceType = .PhotoLibrary
      imagePickerController.allowsEditing = false

      presentViewController(imagePickerController, animated: true, completion: nil)
   }

   func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
      UIImageWriteToSavedPhotosAlbum(image, self, "image:didFinishSavingWithError:contextInfo:", nil)
   }

   func imagePickerControllerDidCancel(picker: UIImagePickerController) {
      self.dismissViewControllerAnimated(true, completion: nil)
   }

   func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafePointer<Void>) {
      guard error == nil else {
         //Error saving image
         return
      }
      //Image saved successfully
   }

}

答案 1 :(得分:7)

以下是在SWIFT 3.0中保存相机胶卷中当前视图的屏幕截图的工作示例

 @IBAction func saveScreenshot(_ sender: Any) {

    //Create the UIImage
    UIGraphicsBeginImageContextWithOptions(editorView.frame.size, false, UIScreen.main.scale)

    //  UIGraphicsBeginImageContext(myTextView.frame.size)
    editorView.layer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIImageWriteToSavedPhotosAlbum(image!, self, #selector(TextEditorViewController.image(_:didFinishSavingWithError:contextInfo:)), nil)

}

func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
if let error = error {
    // we got back an error!
    let ac = UIAlertController(title: "Save error", message: error.localizedDescription, preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "OK", style: .default))
    present(ac, animated: true)
} else {
    let ac = UIAlertController(title: "Saved!", message: "Your image has been saved to your photos.", preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "OK", style: .default))
    present(ac, animated: true)
}

}

答案 2 :(得分:3)

@ Dare的检查错误的解决方案对我没有用(Swift 2.0)。

这种轻微的修改确实有效:

func image(image: UIImage, didFinishSavingWithError: NSError?, contextInfo:UnsafePointer<Void>)       {
        if didFinishSavingWithError != nil
        {
            Helper.showNotifierInfo(DefaultTextFailed)
        }
        else
        {
            Helper.showNotifierInfo(DefaultTextSaved)
        }
    }

答案 3 :(得分:0)

swift 2.2中的另一个例子

此示例的主要区别在于具有回调函数的类必须从NSObject 扩展,(@ objc也可以工作)

func writeImage(){
    let responder = WriteImageToFileResponder()
    responder.addCompletion{ print("completed") }

    let image = UIImage(color: .redColor(), size: CGSize(width: 100, height: 100))!
    UIImageWriteToSavedPhotosAlbum(image, responder, #selector(WriteImageToFileResponder.image(_:didFinishSavingWithError:contextInfo:)), nil)
}

class WriteImageToFileResponder: NSObject {
    var completion: (() -> Void)?

    func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeMutablePointer<Void>) {
        print(error)
        completion?()

    }

    func addCompletion(completion: (() -> Void)? ) {
        self.completion = completion
    }
}

答案 4 :(得分:0)

我从@David Rees 的帖子更新了 Swift 5 版本

import Foundation
class WriteImageToFileResponder: NSObject {
    typealias WriteImageToFileResponderCompletion = ((UIImage?, Error?) -> Void)?
    var completion: WriteImageToFileResponderCompletion = nil
    
    override init() {
        super.init()
    }
    
    @objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
        if (completion != nil) {
            error == nil ? completion?(image, error) : completion?(nil, error)
            completion = nil
        }
    }
    func addCompletion(completion:WriteImageToFileResponderCompletion) {
        self.completion = completion
    }
}

使用

let responder = WriteImageToFileResponder()
responder.addCompletion { (image, error) in
// completion block
}
// pass your image that you want to write 
let previewImage = UIImage(named:"sample")
UIImageWriteToSavedPhotosAlbum(previewImage, responder, #selector(WriteImageToFileResponder.image(_:didFinishSavingWithError:contextInfo:)), nil)