You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跟随教程实现相机/相册选图功能时遭遇无法解决的报错

解决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
        }
    }
}

关键修复说明

  1. 核心修复:在removeImageButton的didSet闭包末尾补上缺失的},让类的结构恢复正常,编译器能正确识别selectedImage等类成员。
  2. 细节优化:修正了present方法调用中的多余空格,让代码更符合Swift规范。

替换代码后重新编译,这两个报错应该就能完全解决了。

内容的提问来源于stack exchange,提问作者24SGR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 13:27:47