【问题标题】:UIImagePickerControllerDelegate not calledUIImagePickerControllerDelegate 未调用
【发布时间】:2018-02-19 18:22:14
【问题描述】:

我有一个独立的类来使用 UIImagePickerController 从相机/照片库中获取图像。

我似乎无法弄清楚为什么没有调用 didFinishPickingMediaWithInfo 或 imagePickerControllerDidCancel 方法..?我意识到这个问题已经被问过很多次了,但我无法弄清楚......我知道所有的方法名称都是正确的。

我已经在 info.plist 中正确设置了以下所有内容:

  • 隐私 - 媒体库使用说明
  • 隐私 - 照片库使用说明
  • 隐私 - 照片库使用说明

import UIKit

class ImagePickerService: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

  fileprivate var completion: ((UIImage) -> ())
  fileprivate var imagePicker: UIImagePickerController

  init(completion: @escaping ((UIImage) -> ())) {
    self.completion = completion
    self.imagePicker = UIImagePickerController()
    super.init()
    imagePicker.delegate = self
  }

  func show(from viewController: UIViewController) {
    showAlert(from: viewController)
  }

  fileprivate func showAlert(from viewController: UIViewController) {
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    alert.addAction(UIAlertAction(title: "Take a photo", style: .default) { _ in
      self.openCamera(from: viewController)
    })
    alert.addAction(UIAlertAction(title: "Choose from library", style: .default) { _ in
      self.openGallery(from: viewController)
    })
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
    viewController.present(alert, animated: true, completion: nil)
  }

  // MARK: Image Picker

  fileprivate func openCamera(from viewController: UIViewController) {
    guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
      viewController.showOKAlert(title: "Error!", message: "No camera available")
      return
    }
    showImagePicker(withSource: .camera, from: viewController)
  }

  fileprivate func openGallery(from viewController: UIViewController) {
    showImagePicker(withSource: .photoLibrary, from: viewController)
  }

  fileprivate func showImagePicker(withSource source: UIImagePickerControllerSourceType, from viewController: UIViewController) {
    imagePicker.sourceType = source
    viewController.present(imagePicker, animated: true, completion: nil)
  }

}

extension ImagePickerService {

  func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    guard let image = info[UIImagePickerControllerEditedImage] as? UIImage else {
      return
    }
    completion(image)
    picker.dismiss(animated: true, completion: nil)
  }

  func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    picker.dismiss(animated: true, completion: nil)
  }

}

编辑: 问题是我没有在实例化时创建对 ImagePickerService 的强引用,它在调用委托方法之前自动释放。

【问题讨论】:

  • 您如何使用ImagePickerService?您是否实例化它并保持对它的强引用?
  • 您应该设置 imagePicker 导航控制器委托:imagePicker.navigationController?.delegate = self
  • @silicon_valley 这就是问题所在,谢谢!

标签: ios swift uiimagepickercontroller swift4


【解决方案1】:

问题出在以下代码sn-p:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    guard let image = info[UIImagePickerControllerEditedImage] as? UIImage else {
      return
    }
    completion(image)
    picker.dismiss(animated: true, completion: nil)
}

您希望始终有经过编辑的图像,但您的照片库中的所有照片可能并非如此。当info[UIImagePickerControllerEditedImage] 返回nil 时,尝试使用UIImagePickerControllerOriginalImage 键。

如果一开始没有调用这些方法,则需要确保对ImagePickerService 实例具有强引用。

例如,此代码有效:

class ViewController: UIViewController {

    var picker: ImagePickerService?

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { [weak self] in
            guard let `self` = self else { return }
            self.picker = ImagePickerService() { (image) in
                print(image)
            }
            self.picker?.show(from: self)
        }
    }

}

【讨论】:

  • 您是否对ImagePickerService 实例保持强引用?
  • 是的,没有对实例保持强引用。谢谢!
【解决方案2】:

尝试创建 ImagePickerService 类的单例:

static let shared = ImagePickerService()

创建单例后,对服务对象的引用将保持不变。

在 init() 中设置 delegate 并创建一个显示 ImagePicker 的方法。

func pickMedia(from: UIViewController?,didPickMedia: ((UIImage) -> ())?){      
            //self.openCamera()
            //or
            //self.openGallery()
}

从那个单例中,您可以将其呈现为:

  ImagePickerService.shared.pickMedia(from: self) { (image) in

  }

【讨论】:

    猜你喜欢
    • 2018-09-01
    • 2011-07-28
    • 1970-01-01
    • 2021-01-27
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    相关资源
    最近更新 更多