跟随教程实现相机/相册选图功能时遭遇无法解决的报错
解决UIImagePickerController图片选择功能中的两个报错
我看了你的代码和遇到的问题,这两个报错其实都是由一个语法结构错误引发的连锁问题,咱们一步步来修复:
错误原因分析
- "类型'ViewController'没有成员'selectedImage'":
你的removeImageButton的didSet闭包没有正确闭合,导致selectedImage属性、viewDidLoad方法等代码被错误地嵌套在removeImageButton的作用域内,编译器根本找不到selectedImage这个类成员。 - "nil无法赋值给类型'(UIImagePickerController, [UIImagePickerController.InfoKey : Any]) -> ()'":
这是第一个语法错误引发的连锁问题——编译器无法正确解析你的ViewController类结构,自然也无法识别你在extension中实现的UIImagePickerControllerDelegate协议方法,进而认为controller.delegate = self的赋值不合法。
修复后的完整代码
我已经帮你修正了语法错误,同时调整了一处代码规范细节:
public var imagePickerController: UIImagePickerController? public var defaultImageUrl: URL? internal var selectedImage: UIImage? { get { return self.selectedImageView.image } set { switch newValue { case nil: self.selectedImageView.image = nil self.selectImageButton.isEnabled = true self.selectImageButton.alpha = 1 self.removeImageButton.isEnabled = false self.removeImageButton.alpha = 0.5 default: self.selectedImageView.image = newValue self.selectImageButton.isEnabled = false self.selectImageButton.alpha = 0.5 self.removeImageButton.isEnabled = true self.removeImageButton.alpha = 1 } } } //This outlet, 'selectedImageContainer' was guessed from observing the tutorial stacked their UIImageView in a UIView. @IBOutlet weak var selectedImageContainer: UIView! @IBOutlet weak var selectedImageView: UIImageView! @IBOutlet weak var selectImageButton: UIButton! { didSet { guard let button = self.selectImageButton else { return } button.isEnabled = true button.alpha = 1 } } @IBOutlet weak var removeImageButton: UIButton! { didSet { guard let button = self.removeImageButton else { return } button.isEnabled = false button.alpha = 0.5 } } // 补上缺失的闭合大括号,修正类结构 override func viewDidLoad() { super.viewDidLoad() self.selectedImageView.contentMode = .scaleAspectFit self.selectImageButton.isEnabled = self.selectedImage == nil self.selectImageButton.alpha = 1 } @IBAction func selectImageButtonAction(_ sender: Any) { if self.imagePickerController != nil { self.imagePickerController?.delegate = nil self.imagePickerController = nil } self.imagePickerController = UIImagePickerController.init() let alert = UIAlertController.init(title: "Select Source Type", message: nil, preferredStyle: .actionSheet) if UIImagePickerController.isSourceTypeAvailable(.camera) { alert.addAction(UIAlertAction.init(title: "Camera", style: .default, handler: { (_) in self.presentImagePicker(controller: self.imagePickerController!, source: .camera) })) } if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { alert.addAction(UIAlertAction.init(title: "Photo Library", style: .default, handler: { (_) in self.presentImagePicker(controller: self.imagePickerController!, source: .photoLibrary) })) } if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) { alert.addAction(UIAlertAction.init(title: "Saved Albums", style: .default, handler: { (_) in self.presentImagePicker(controller: self.imagePickerController!, source: .savedPhotosAlbum) })) } alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel)) self.present(alert, animated: true) } internal func presentImagePicker(controller: UIImagePickerController , source: UIImagePickerController.SourceType) { controller.delegate = self controller.sourceType = source self.present(controller, animated: true) // 修正多余空格,符合代码规范 } @IBAction func removeImageButtonAction(_ sender: UIButton) { self.selectedImage = nil } extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return self.imagePickerControllerDidCancel(picker) } self.selectedImage = image picker.dismiss(animated: true) { picker.delegate = nil self.imagePickerController = nil } } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true) { picker.delegate = nil self.imagePickerController = nil } } }
关键修复说明
- 核心修复:在
removeImageButton的didSet闭包末尾补上缺失的},让类的结构恢复正常,编译器能正确识别selectedImage等类成员。 - 细节优化:修正了
present方法调用中的多余空格,让代码更符合Swift规范。
替换代码后重新编译,这两个报错应该就能完全解决了。
内容的提问来源于stack exchange,提问作者24SGR
相关产品推荐
相关产品推荐

