图像select器控制器委托在单独的类不起作用

我是Xcode和Swift的新手。 我目前正在玩Apple 开始开发iOS应用(Swift)教程。

一切正常,除了一件事。 本教程处理主ViewController类中的Image Picker委托,使其符合UIImagePickerControllerDelegateUINavigationControllerDelegate协议。 我想尝试一些其他的东西,并把委托移动到单独的类。 以下是我所做的:

 import UIKit import Foundation class MealPhotoDelegate: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { var placeholder: UIImageView? func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { dismiss(animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { fatalError("Expected a dictionary containing an image, but was provided the following: \(info)") } placeholder!.image = selectedImage dismiss(animated: true, completion: nil) } } 

ViewController

 @IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) { nameTextField.resignFirstResponder() let imagePickerController = UIImagePickerController() imagePickerController.sourceType = .photoLibrary let imagePickerDelegate = MealPhotoDelegate() imagePickerDelegate.placeholder = photoImageView imagePickerController.delegate = imagePickerDelegate present(imagePickerController, animated: true, completion: nil) } 

每次图像选取器出现,当我浏览照片时,都会产生错误:

2017-07-20 01:49:00.937470 + 0200 FoodTracker [41600:4236501] API错误:(null)返回0宽度,假设UIViewNoIntrinsicMetric

我究竟做错了什么? UIViewController是一个委托的超类的好select? 我觉得可能不是。

你的问题是内存pipe理。 在你的selectImageFromPhotoLibrary里面,你创build了一个selectImageFromPhotoLibrary的本地实例。 在方法结束时,这个实例超出了范围,因为没有强引用而被取消分配。 因此,图像select器的代表变成nil ,不起作用。

解决scheme是对MealPhotoDelegate的实例做一个强有力的参考。 这很容易使用视图控制器类中的属性完成。

将以下属性添加到您的视图控制器类:

 var imagePickerDelegate: MealPhotoDelegate? 

然后更新这一行:

 let imagePickerDelegate = MealPhotoDelegate() 

有:

 imagePickerDelegate = MealPhotoDelegate() 

而已。 它现在会工作。

作为一个方面说明,没有理由为什么你的MealPhotoDelegate应该扩展UIViewController 。 让它扩展NSObject 。 而你通过使用正确的代码解决了新的问题。

这是应该如何:

 class MealPhotoDelegate: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { var placeholder: UIImageView? func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { fatalError("Expected a dictionary containing an image, but was provided the following: \(info)") } if let placeholder = placeholder { placeholder.image = selectedImage } picker.dismiss(animated: true, completion: nil) } }