我是Xcode和Swift的新手。我目前正在玩Apple的Start Developing iOS Apps (Swift)教程。
到目前为止一切正常,除了一件事。本教程处理主ViewController
类中的Image Picker委托,使其符合UIImagePickerControllerDelegate
和UINavigationControllerDelegate
协议。我想尝试别的东西并将委托移到单独的类。这就是我的所作所为:
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
是否可以选择代表的超类?我觉得可能不是。
答案 0 :(得分:2)
您的问题是内存管理问题。在selectImageFromPhotoLibrary
内,您可以创建MealPhotoDelegate
的本地实例。在方法结束时,此实例超出范围并被取消分配,因为没有强引用。因此,图片选择器的代理人变为nil
,但它无法正常工作。
解决方案是强烈引用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)
}
}