无法使用类型为'UIImagePickerController.InfoKey'的索引来访问类型为'[String : Any]'的值

66

我正在使用苹果的Swift iOS教程,出现了一个错误:

无法使用'UIImagePickerController.InfoKey'类型的索引来访问'[String : Any]'类型的值。

他们定义的函数如下。

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    // The info dictionary may contain multiple representations of the image. You want to use the original.
    guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }

    // Set photoImageView to display the selected image.
    photoImageView.image = selectedImage

    // Dismiss the picker.
    dismiss(animated: true, completion: nil)
}

我正在使用 Xcode 版本 10.0 beta 3,其中包含 Swift 4.2。

我想了解如何遍历文档以了解可能发生了什么更改或故障。


我注意到本教程后面的另一行代码也报错了 - button.addTarget(self, action: #selector(RatingControl.ratingButtonTapped(button:)), for: .touchUpInside)。如果其他人遇到同样的问题 - 我通过在类行的开头添加@objcMembers来解决它,就像这样:@objcMembers class RatingControl: UIStackView {。请参见https://www.hackingwithswift.com/example-code/language/how-to-fix-argument-of-selector-refers-to-instance-method-that-is-not-exposed-to-objective-c。 - Keara
8个回答

118

在Swift 4.2中,该方法的签名已更改。

func imagePickerController(_ picker: UIImagePickerController, 
  didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])

你需要写作

guard let selectedImage = info[.originalImage] as? UIImage else {
    fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}

通过阅读文档或注释掉整个方法,重新键入前几个字符并使用代码自动完成,您可以自行了解此类术语的更改。


太好了,它已经清除了IDE中的错误。像OP一样,我刚开始学习iOS并跟随同样的教程。 - Vijay Kumar Kanta
1
有没有人在使用 "as?" 时遇到 "'UIImage?' 无法转换为 'UIImage'" 这样的错误? - The Anh Nguyen

27

我也在按照同样的教程进行学习,更新后的代码如下:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    // The info dictionary may contain multiple representations of the image. You want to use the original.
    guard let selectedImage = info[.originalImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }

    // Set photoImageView to display the selected image.
    photoImageView.image = selectedImage

    // Dismiss the picker.
    dismiss(animated: true, completion: nil)
}

20

Swift 5

在最新版本的 Swift 4 或 5 中,代理方法如下所示,应该有效:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    // Code here
}

使用,

guard let selectedImage = info[.editedImage] as? UIImage else {

}



func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    guard let selectedImage = info[.editedImage] as? UIImage else {

    }
}

9

使用方法如下:

guard let selectedImage = info[UIImagePickerController.InfoKey.originalImage.rawValue] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}

8
在 Swift 4 和 5 中,如下所示:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    guard let selectedImage = info[.editedImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }

    self.myImageView.image = selectedImage

    picker.dismiss(animated: true, completion: nil)
}

Swift 4和5之间没有区别。 - vadian

3

我也在跟着教程学习,按照下面的更改后已经可以正常运行了。

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    // The info dictionary may contain multiple representations of the image. You want to use the original.
    guard let selectedImage = info[.originalImage] as? UIImage
        else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }

    // Set photoImageView to display the selected image.
    photoImageView.image = selectedImage

    // Dismiss the picker.
    dismiss(animated: true, completion: nil)
}

我正在使用 XCode 11 和 Swift 5。


1

在 Swift 4.2 中,Method 已经有了一些变化。

首先初始化这两个变量:

var imagePicker = UIImagePickerController()
var pickedImageProduct = UIImage()

extension yourViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{
//create an IBAction to access Camera
    @IBAction func accessCameraBtn(_ sender: UIButton) {
        imagePicker.delegate = self
        imagePicker.sourceType = UIImagePickerController.SourceType.camera
        self.present(imagePicker, animated: true, completion: nil)
    }
//create an IBAction to access Gallery
    @IBAction func accessGalleryBtn(_ sender: UIButton) {
        imagePicker.delegate = self
        imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
        self.present(imagePicker, animated: true, completion: nil)
    }
//Final step put this Delegate    
    func imagePickerController(_ picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        guard let selectedImage = info[.originalImage] as? UIImage else {
           Print("Error: \(info)")
        }

            pickedImageProduct = selectedImage

        dismiss(animated: true, completion: nil)
     }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {

        dismiss(animated: true, completion: nil)
    }

}

这个方法已经被更改了,我认为是在4.0或者更早的版本。 - Sulthan

1
在Swift 4.2中,您可以将函数编写为:


    func photoLib()
    {
        //opens Photo Library, call the function in a @IBAction func
        let myPickerController = UIImagePickerController()
        myPickerController.delegate = self;
        myPickerController.sourceType = 
        UIImagePickerController.SourceType.photoLibrary
        myPickerController.allowsEditing = true
        present(myPickerController, animated: true)
    }


    func imagePickerController(_ picker: UIImagePickerController, 
    didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    picker.dismiss(animated: true)

    guard let image = info[.editedImage] as? UIImage else {
        print("No image found")
        photoLabel.text = "Photo Not Found"
        return
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接