【问题标题】:Using completionSelector and completionTarget with UIImageWriteToSavedPhotosAlbum将 completionSelector 和 completionTarget 与 UIImageWriteToSavedPhotosAlbum 一起使用
【发布时间】:2021-07-29 22:15:08
【问题描述】:

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

我能想到的唯一方法是使用某种形式的 if/else 循环(正如您将在下面的伪代码 cmets 中看到的那样),但我想不出任何语法可以使用 @来自 UIKit 的 987654321@ 函数。我在 Apple 的开发站点上遇到过使用 completionSelector 和 completionTarget 的建议,但我真的不明白如何使用它们,或者我的代码中的 completionSelector 和 completionTarget 应该使用什么特定的用语。我对 Swift 比较陌生。

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

func screenshotMethod()
{
    UIGraphicsBeginImageContextWithOptions(HighchartsView.scrollView.contentSize, false, 0);
    view.layer.renderInContext(UIGraphicsGetCurrentContext())
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
    //if saved to Camera Roll
    //            {
    //              confirmScreenshot()
    //            }
    //        
    //else 
    //        {
    //            exit code/stop 
    //        }


}


func confirmScreenshot()
{
    let alertController = UIAlertController(title: "Success", message: "This chart has been successfully saved to your Camera Roll.", preferredStyle: .Alert)
    let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
    alertController.addAction(defaultAction)

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

【问题讨论】:

    标签: ios swift uiimage screenshot alert


    【解决方案1】:
    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
       }
    
    }
    

    【讨论】:

    • 你知道如何将它更新到 Swift 2.1 吗?
    • 为 swift 2.1 更新
    • 如果 contextInfo 对象不是 nil 来看看它是如何解开的,那就太好了。
    【解决方案2】:

    这是一个工作示例,用于在 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)
    }
    

    }

    【讨论】:

    • 我无法让它为我工作任何想法? UIImageWriteToSavedPhotosAlbum(imageToSave, #selector(PreviewViewController.image(:didFinishSavingWithError:contextInfo:)), nil, nil)` 并定义为`@objc func image( image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafePointer) `
    【解决方案3】:

    @Dare 的错误检查解决方案对我不起作用(Swift 2.0)。

    这个小小的修改确实奏效了:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        我从@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)
        

        【讨论】:

        • 这应该是正确的答案。
        猜你喜欢
        • 1970-01-01
        • 2016-02-24
        • 2010-11-22
        • 2020-05-01
        • 2022-01-24
        • 2014-06-09
        • 2013-01-18
        • 2013-11-06
        • 2021-04-27
        相关资源
        最近更新 更多