Sathoshi K Sathoshi K - 1 month ago 6
Swift Question

UIImagePickerControllerDeletage is not being called

I am trying to create an controller to handle all image functionality so that you can easily bind all camera actions from any view controller.

Ideally what my goal was to create a class with a function that returns an UIImage and allow my self to write individual completion handlers

ie.

let imagePicker = ImagePickerAlertController(frame:self.view.frame,controller:self)
imagePicker.displayAlert(){
imageValue in if let image = imageValue {
myImageView.image = image
}
}


However, i cannot seem to save the image or even access the image that i have taken from the camera. The imagePickerController function does not seem to be hitting.

import UIKit

class ImagePickerAlertController: UIView, UIImagePickerControllerDelegate,UINavigationControllerDelegate {

var UIViewController : UIViewController?

let imagePicker: UIImagePickerController! = UIImagePickerController()

init(frame: CGRect, controller: UIViewController){

self.UIViewController = controller
super.init(frame:frame)

}

required init?(coder aDecoder: NSCoder) {

self.UIViewController = nil
super.init(coder: aDecoder)
}

public func displayAlert(){
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

let galleryAction = UIAlertAction(title: "Choose Photo",style:.default) {action -> Void in print("ok")}
let cameraAction = UIAlertAction(title: "Take Photo",style:.default) {action -> Void in self.takePicture() }
let cancelAction = UIAlertAction(title: "Cancel",style:.cancel) {action -> Void in }

alert.addAction(cancelAction)
alert.addAction(cameraAction)
alert.addAction(galleryAction)

self.UIViewController?.present(alert,animated:true,completion:nil)

}

private func takePicture() {

if (UIImagePickerController.isSourceTypeAvailable(.camera)){
if UIImagePickerController.availableCaptureModes(for: .rear) != nil || UIImagePickerController.availableCaptureModes(for: .front) != nil{
imagePicker.allowsEditing = false
imagePicker.sourceType = .camera
imagePicker.cameraCaptureMode = .photo
imagePicker.delegate = self
self.UIViewController?.present(imagePicker,animated: true,completion: nil)
}
else {
postAlert(title: "Rear camera doesn't exist",message:"Application cannot access the camera.")
}

}
else {
postAlert(title: "Camera inaccessable",message:"Application cannot access the camera.")
}
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("got image")
if let pickedImage:UIImage = (info[UIImagePickerControllerOriginalImage]) as? UIImage {
let selectorToCall = Selector(("imageWasSavedSuccessfully:didFinishSavingWithError:context:"))
UIImageWriteToSavedPhotosAlbum(pickedImage, self, selectorToCall, nil)
}
imagePicker.dismiss(animated: true,completion: nil)
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("cancel")
self.UIViewController?.dismiss(animated: true, completion: nil)
}

func imageWasSavedSuccessfully(image: UIImage, didFinishSavingWithError error : NSError!, context: UnsafeMutablePointer<()>){
print("image saved")
if (error) != nil {
print(error)
}
else {
print("good to go")
}
}


func postAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.UIViewController?.present(alert, animated: true, completion: nil)
}

}

Answer

The problem is that you try to present imagePicker when your UIViewController already has a modal view controller presented above.

displayAlert():

self.UIViewController?.present(alert,animated:true,completion:nil)

takePicture():

self.UIViewController?.present(imagePicker,animated: true,completion: nil)

So you should dismiss UIAlertController as soon as you don't need it:

let cameraAction = UIAlertAction(title: "Take Photo",style:.default) {action -> Void in
    alert.dismiss(animated: true, completion: nil)
    self.takePicture()        
}

Now viewController can present without any issues