I have a class
class ActivitiesMainPageController: UICollectionViewController ,UIImagePickerControllerDelegate, UINavigationControllerDelegate{
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
switch indexPath.item {
case 0 :
let takePictureInstance = takePictures()
takePictureInstance.presentCamera()
}
}
The takePictures() is s custom class
class takePictures: UIViewController, UIImagePickerControllerDelegate, UIAlertViewDelegate, UINavigationControllerDelegate
{
var imagePicker: UIImagePickerController! = UIImagePickerController()
func presentCamera()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)
{
let objViewController = UIApplication.shared.keyWindow?.rootViewController
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = false
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
objViewController?.present(imagePicker,animated: true,completion: nil)
}
else
{
// error msg
print ("error displaying Camera")
noCamera()
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
print(self.Tag + "image picker controller")
self.dismiss(animated: true, completion: nil)
}
}
The didfinishpickingimage never gets triggered. I don't see the print statement. After reading the SO here, I think I am not doing the delegate correctly. Can you please help?
The problem is in your ActivitiesMainPageController
class. It's a memory management issue. You create a local instance of your takePictures
class (FYI - class names should start with uppercase letters), and then call the presentCamera
method. And then the takePictureInstance
variable immediately goes out of scope. This means it has no more references and it gets deallocated.
So at this point, the image picker's (weak) delegate becomes nil
. This is why the image picker delegate method is never called.
There are two ways to fix this:
takePictures
instance inside your ActivitiesMainPageController
class (use a property instead of a local variable). But this has the problem of not knowing when to release the instance.takePictures
class where it keeps a strong reference to itself when created, and then releases that strong reference after the image picker is dismissed.Option 2 can be implemented like this:
class takePictures: UIViewController, UIImagePickerControllerDelegate, UIAlertViewDelegate, UINavigationControllerDelegate
{
var strongSelf: takePictures?
var imagePicker: UIImagePickerController! = UIImagePickerController()
func presentCamera()
{
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera)
{
let objViewController = UIApplication.shared.keyWindow?.rootViewController
imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = false
imagePicker.sourceType = UIImagePickerControllerSourceType.camera
objViewController?.present(imagePicker,animated: true,completion: nil)
strongSelf = self // keep me around
}
else
{
// error msg
print ("error displaying Camera")
noCamera()
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
print(self.Tag + "image picker controller")
self.dismiss(animated: true, completion: nil)
strongSelf = nil // let me go
}
}