Sathoshi K
Sathoshi K

Reputation: 203

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)
  }

}

Upvotes: 0

Views: 72

Answers (1)

alexburtnik
alexburtnik

Reputation: 7741

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

Upvotes: 2

Related Questions