23

I have a UITableViewCell button to take an image and place it back in the cell. When I call the UIImagePickerController and take the image, it doesn't call the following delegate:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject], sender:AnyObject)

This is my takePhotoFunction in UITableViewController:

@IBAction func takePhoto(sender: AnyObject) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.allowsEditing = true

let actionSheet = UIAlertController(title: "Choose image souruce", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)

actionSheet.addAction(UIAlertAction(title: "Take Image", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
    imagePickerController.sourceType = UIImagePickerControllerSourceType.Camera
    self.presentViewController(imagePickerController, animated: true, completion: nil)
}))

actionSheet.addAction(UIAlertAction(title: "Photo Library", style: UIAlertActionStyle.Default, handler: { (alert:UIAlertAction!) -> Void in
    imagePickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
    self.presentViewController(imagePickerController, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
self.presentViewController(actionSheet, animated: true, completion: nil)}
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Tal Zion
  • 6,308
  • 3
  • 50
  • 73

13 Answers13

43

In Swift 3, this delegate method is now called:

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

The differences are:

  1. There is an underline _ before picker
  2. info type at the end is changed from [String : AnyObject] to [String : Any]

I had the same issue and when I made these changes it worked.

JPetric
  • 3,838
  • 28
  • 26
17

1. Dont forget to add UIImagePickerControllerDelegate,UINavigationControllerDelegate
2. In your viewDidLoad() add picker.delegate = self
3. Add the delegate methods

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let chosenImage = info[UIImagePickerControllerOriginalImage] as! UIImage 
        userImageView.contentMode = .scaleAspectFit
        userImageView.image = chosenImage
        dismiss(animated:true, completion: nil)
    }

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

Hope it helps :)

Vinu David Jose
  • 2,569
  • 1
  • 21
  • 38
7

For swift 4.2

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
   if let chosenImage = info[.originalImage] as? UIImage{
        //use image
    }
}
Atul Pol
  • 341
  • 3
  • 5
3

With the Swift 5 we have slight update.

Here is single screen example I have created to test this with iOS 12.2

import UIKit


class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //MARK: Open Photos Galley Button Action method
    @IBAction func openPhotosGallery(_ sender: Any) {

        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
            let myPickerController = UIImagePickerController()
            myPickerController.delegate = self;
            myPickerController.sourceType = .photoLibrary
            self.present(myPickerController, animated: true, completion: nil)
        }
    }

    //MARK: ImagePicker Controller Delegate methods
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        self.dismiss(animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let chosenImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        imageView.image = chosenImage
        dismiss(animated:true, completion: nil)
    }
}
Tal Zion
  • 6,308
  • 3
  • 50
  • 73
swiftBoy
  • 35,607
  • 26
  • 136
  • 135
2

Use below method for Swift 4.2:

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
}
Nupur Sharma
  • 1,106
  • 13
  • 15
2

For Swift 4.2

This method has renamed and now should be called as below. I had the same issue that this delegate method was not calling but after this, my issue resolved.

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

}
Noshaid Ali
  • 127
  • 1
  • 12
1

for SWIFT 4.2

I had a similar issue when delegate methods were not called by program.

The imagePicker.delegate = self should be NOT in viewDidLoad() method but in method which opens gallery. Like this:

func openGallery()
    {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self

        imagePicker.sourceType = .photoLibrary

        self.present(imagePicker, animated: true, completion: nil)
   }
Almazini
  • 1,825
  • 4
  • 25
  • 48
1

In Swift 5 we need to use:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])  {
Anil Kumar
  • 1,830
  • 15
  • 24
  • 1
    Worked for me. As I added a tap gesture recognizer to a UIView, the user taps the UIView but the selected image didn't allocate after picker dismiss and the method I used was yellow lined. This method above solved my problem. Thanks – AdPiscinam Dec 11 '22 at 11:41
0

You have to use that method in this way as there is no delegate method that u have declared:

func imagePickerController(picker: UIImagePickerController!, didFinishPickingMediaWithInfo info:[NSObject : AnyObject]) {
        println("Calling")       
}

Reference for Apple Document :https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIImagePickerControllerDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIImagePickerControllerDelegate/imagePickerController:didFinishPickingMediaWithInfo:

Dheeraj Singh
  • 5,143
  • 25
  • 33
  • Hi Dheeraj, thanks for your answer. I have implemented the delegate method but after the imagpepickercontroller has completed, this method is not called. – Tal Zion Mar 24 '15 at 21:31
  • did you use the delegate method that i mentioned because you delegate method is not correct and there is no delegate method as u have declared. – Dheeraj Singh Mar 25 '15 at 04:45
0

The delegate method is now called func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])

I see your imagePickerController.delegate is correctly set so I would assume that you accidently put the didFinishPickingMediaWithInfo code outside your ViewController class

budiDino
  • 13,044
  • 8
  • 95
  • 91
0

If your UIImagePickerController() object has allowsEditing property set to true then you should get the image in the delegate method as:

if allowsEditing == true

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

        if let pickedImage = info[.editedImage] as? UIImage {

              //do something with image

        }

           dismiss(animated: true, completion: nil)

    }

if allowsEditing == false

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

            if let pickedImage = info[.originalImage] as? UIImage {

                  //do something with image

            }

               dismiss(animated: true, completion: nil)

        }
Frankenxtein
  • 483
  • 7
  • 18
0

Maybe sometimes it is caused by ARC? I declare a variable of adapter (present UIImagePickerController for pre-iOS14 below or present PHPickerViewController for iOS 14+) in controller instead in function. It works for me.

var adapter: PHPickerAdapter?

@objc func openGallery(recognizer: UITapGestureRecognizer) {
    adapter = PHPickerAdapter()
    adapter?.delegate = self
    adapter?.showPhotoPicker(.photoLibrary, from: self)
}
Pranav Kasetti
  • 8,770
  • 2
  • 50
  • 71
moon
  • 1
0

In my case the issue was because the picker was declared inside a function so it get deallocated once we exit the function

func showImagePicker() {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    present(imagePicker, animated: true)
}

The solution was to move the imagePicker object to outside the function body

lazy var imagePicker = UIImagePickerController()
func showImagePicker() {
    imagePicker.delegate = self
    present(imagePicker, animated: true)
}

I made it lazy var since I want to initialize it only when needed.

Musa almatri
  • 5,596
  • 2
  • 34
  • 33