0

I'm in the middle of replacing UIImagePickerController with PHPickerViewController for iOS 14, but I'm having issues displaying the selected photo in the UI using PHPickerViewController. When I select a photo from the Photo Library, the PHPickerViewController dismisses itself without updating the photo in the UI. I've been trying different solutions from various tutorials, but I'm getting the same result each time.

Below is the code I have currently. The code within the DispatchQueue.main.async brackets is what I have been using for UIImagePickerController to display the photo in the UI.

extension EditProfileController: PHPickerViewControllerDelegate {
    @available(iOS 14, *)

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true, completion: nil)

        for result in results {
            result.itemProvider.loadObject(ofClass: UIImage.self) { object, error in
                if let image = object as? UIImage {
                    DispatchQueue.main.async {
                        self.profileImageView.image = image
                        self.imageChanged = true
                    }
                }
            }
        }
    }
}
safetotry
  • 67
  • 6
  • Surely the line "picker.dismiss(animated: true, completion: nil)" should only be called after the photo has successfully been updated? Move it below "self.imageChanged" in the DispatchQueue callback. – teacup Sep 07 '21 at 01:48
  • That doesn't work unfortunately and just freezes the PHPickerViewController. I've tried moving it to other places, like below and outside the for loop, but getting the same result. – safetotry Sep 07 '21 at 02:13

1 Answers1

0

There's nothing much wrong with your code. I would have written it this way, but it's pretty much the same thing:

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true) {
        guard let result = results.first else { 
            print("no results")
            return 
        }
        let prov = result.itemProvider
        guard prov.canLoadObject(ofClass: UIImage.self) else { 
            print("no image")
            return
        }
        prov.loadObject(ofClass: UIImage.self) { object, error in
            if let image = object as? UIImage {
                DispatchQueue.main.async {
                    self.profileImageView.image = image
                    self.imageChanged = true
                }
            } else {
                print(error as Any)
            }
        }
    }
}

Try it like that, just as an experiment, since we know that it normally works. Use breakpoints and the console messages to make sure the path of execution is going where you expect. If it does, but the display of the image still doesn't work, I'd have to suggest that the problem lies elsewhere, in code you're not showing us.

matt
  • 515,959
  • 87
  • 875
  • 1,141