Search code examples
swiftxcodecameraimagepicker

Alert not showing in the ImagePicker


I want to offer the option to use either the photo library or the camera, but my alert to select either photos or use a camera doesn't show up when I add the present actionSheet. The compiled application goes straight to photo album without giving me the option to select camera or photo library.

This is the log from my Xcode 11:

2020-06-15 23:05:22.931477-0400 MeMe[6298:3505455] Attempt to present on which is waiting for a delayed presention of to complete 2020-06-15 23:05:22.931653-0400 MeMe[6298:3505455] Attempt to present on which is waiting for a delayed presention of to complete error in connection_block_invoke_2: Connection interrupted

This is my code:

import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {

    // OUTLETS *******************************************

    // Image
    @IBOutlet weak var imageView: UIImageView!

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

    // ACTIONS *******************************************    

    // Button
    @IBAction func pickImage(_ sender: Any) {

        let imagePickerController = UIImagePickerController()
        // set imagePickerController as delegate
        imagePickerController.delegate = self

        // provide actionSheet to display the camera and photo  options
        let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", preferredStyle: .actionSheet)

        // add camera action to imagePickerController
        actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler:{(action:UIAlertAction) in

            // check if the camera is available
            if UIImagePickerController.isSourceTypeAvailable(.camera) {
                imagePickerController.sourceType = .camera
            }
            else {
                print("Camera not available")
            }

        }))

        self.present(imagePickerController, animated: true, completion: nil)

        // add photos action to imagePickerController
        actionSheet.addAction(UIAlertAction(title: "Photos", style: .default, handler:{(action:UIAlertAction) in imagePickerController.sourceType = .photoLibrary}))

        self.present(imagePickerController, animated: true, completion: nil)

        // cancel
        actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

        self.present(actionSheet, animated: true, completion: nil)
    }

    // assign image to imageView

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

        let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage

        imageView.image = image

        picker.dismiss(animated: true, completion: nil)

    }

    // dismiss the image selector

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {

        picker.dismiss(animated: true, completion: nil)

    }


    }




Solution

  • You're trying to present the actionSheet after presenting imagePickerController which is not possible. You need to present the imagePickerController in the UIAlertAction's handler block. Here's the code:

    @IBAction func pickImage(_ sender: Any) {
    
        let imagePickerController = UIImagePickerController()
        // set imagePickerController as delegate
        imagePickerController.delegate = self
    
        // provide actionSheet to display the camera and photo  options
        let actionSheet = UIAlertController(title: "Source", message: "Take a picture or select a photo", preferredStyle: .actionSheet)
    
        // add camera action to imagePickerController
        actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler:{(action:UIAlertAction) in
    
            // check if the camera is available
            if UIImagePickerController.isSourceTypeAvailable(.camera) {
                imagePickerController.sourceType = .camera
            }
            else {
                print("Camera not available")
            }
    
            self.present(imagePickerController, animated: true, completion: nil)
        }))
    
    
        // add photos action to imagePickerController
        actionSheet.addAction(UIAlertAction(title: "Photos", style: .default, handler:{(action:UIAlertAction) in
            imagePickerController.sourceType = .photoLibrary
            self.present(imagePickerController, animated: true, completion: nil)
        }))
    
    
        // cancel
        actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
    
        self.present(actionSheet, animated: true, completion: nil)
    }