我有一个独立的类,可以使用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的强引用,并且在调用委托方法之前它是自动发布的。
答案 0 :(得分:3)
问题出现在以下代码段中:
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)
}
您希望始终有经过编辑的图像,但照片库中的所有照片可能并非如此。当UIImagePickerControllerOriginalImage
返回info[UIImagePickerControllerEditedImage]
时,请尝试使用nil
密钥。
如果首先没有调用这些方法,则需要确保对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)
}
}
}
答案 1 :(得分:0)
尝试创建ImagePickerService类的单例:
static let shared = ImagePickerService()
创建单例后,将维护对服务对象的引用,并且不会释放它。
在init()中设置委托并创建一个显示ImagePicker的方法。
func pickMedia(from: UIViewController?,didPickMedia: ((UIImage) -> ())?){
//self.openCamera()
//or
//self.openGallery()
}
从单身人士中你可以将其呈现为:
ImagePickerService.shared.pickMedia(from: self) { (image) in
}