Search code examples
iosswiftxcodeuiimagepickercontroller

How to pass selected image from UIImagePicker to the UIViewController


I've implemented a UIImagePicker into my app, but I'm struggling to pass the UIImage to the UIViewController that the picker was initiated from (see comment in code below)

The below code is an extension stored in Extensions/ImageUploader.swift

import UIKit
import Firebase

extension UIViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{


    public func ImagePicker() {
        let picker = UIImagePickerController()
        picker.delegate = self
        picker.allowsEditing = true
        // mediaType is image only by default

        present(picker, animated: true, completion: nil)

    }


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

        var selectedImageFromPicker: UIImage?

        if let editedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
            selectedImageFromPicker = editedImage
        }
        if let originalImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            selectedImageFromPicker = originalImage
        }

        picker.dismiss(animated: true, completion:{print("Image upload started")})// Closing the window before the upload, so upload can continue in background while user finishes the form

           // Here I want to pass the selectedImageFromPicker to the ViewController that initiated the imagePicker - how do I do that??


        })
        }
}

In the createActivityVC, I have this IBAction to get access to photo library and initiative the picker - self.imagePicker()

@IBAction func addPictureBtnWasPressed(_ sender: Any) {

    PHPhotoLibrary.requestAuthorization({(status:PHAuthorizationStatus) in
        switch(status) {

       case .notDetermined:

        // Access has not been determined.
        PHPhotoLibrary.requestAuthorization({ (newStatus) in

            if (newStatus == PHAuthorizationStatus.authorized) {
                // Access has been granted.

                self.imagePicker() 
            }

            else {

            }
        })
        break

    case .restricted:
        break

    case .denied:
        // Access has been denied.
        print("Acccess to photo denied")
        break

    case .authorized:
        // Access has been granted.
        print("Access to photo authorized")

         self.imagePicker()

         break


      }
   })
}

I want to pass the selectedImageFromPicker to viewController createActivityVC. How can this be done? I would prefer to not name the viewController specifically but rather make it so that it is dynamic so the imagePicker can be used across multiple ViewControllers if possible.


Solution

  • In your form, have you implemented a UIImageView? If it's the case, in your

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

    you can say:

    myFormImageView.image = selectedImageFromPicker
    

    and then when you submit your form you can upload the form info + the image data

    UPDATE:

    My approach by subclassing UIIMagePickerController

    import UIKit
    
    protocol ImagePickerDelegate {
        func imagePicked(image: UIImage)
    }
    
    class myPickerViewController: UIImagePickerController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
    
        var imagePickerDelegate:ImagePickerDelegate!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            allowsEditing = true
            delegate = self
        }
    
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
            let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
                imagePickerDelegate.imagePicked(image: selectedImage)
            dismiss(animated: true, completion: nil)
        }
    
    }
    
    class ViewController : UIViewController, ImagePickerDelegate {
    
        func imagePicked(image: UIImage) {
            imagePicked = image
        }
    
    
        var imagePicked:UIImage! {
            didSet {
                imageView.image = imagePicked
            }
        }
    
        let button: UIButton = {
           let button = UIButton()
            button.translatesAutoresizingMaskIntoConstraints = false
            button.setTitle("Select an image", for: .normal)
            button.backgroundColor = .red
            button.addTarget(self, action: #selector(handleImagePicker), for: .touchUpInside)
            return button
        }()
    
        let imageView: UIImageView = {
            let iv = UIImageView()
            iv.translatesAutoresizingMaskIntoConstraints = false
            iv.contentMode = .scaleAspectFill
            iv.layer.masksToBounds = true
            iv.layer.borderWidth = 2
            iv.layer.borderColor = UIColor.black.cgColor
            return iv
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            title = "Get image via Delegate"
            view.backgroundColor = .white
    
            view.addSubview(button)
            view.addSubview(imageView)
    
            button.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100).isActive = true
            button.heightAnchor.constraint(equalToConstant: 30).isActive = true
            button.widthAnchor.constraint(equalToConstant: 150).isActive = true
            button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    
            imageView.topAnchor.constraint(equalTo: self.button.topAnchor, constant: 50).isActive = true
            imageView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 20).isActive = true
            imageView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -20).isActive = true
            imageView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -50).isActive = true
    
        }
    
        @objc func handleImagePicker() {
            let myPickerVC = myPickerViewController()
            myPickerVC.imagePickerDelegate = self
    
            self.present(myPickerVC, animated: true, completion: nil )
        }
    
    }
    

    You create a new project and paste the entire code it will works, I guess, like me. Hope it helps