Noa Souccar
Noa Souccar

Reputation: 1

When I present my UIImagePickerController, nothing comes up

What I'm trying to do is present an alert, where the user eaither presess get photo from camera, or photolibrary. However, when I press library, the UIImagePickerViewController doesn't present. I am adding UIAlert actions to the ALert, and the handler of which I am passing in is as a function which presents the ImagePicker controller. What am I doing wrong? I suspect it has to do with how I am presenting the ImagePickerViewController, but I'm not sure. I read the apple docs and they said that a popover is the only style to present it.

import UIKit
import Firebase

class SignupViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    @IBOutlet weak var ProfilePic: UIButton!

    //When button is pressed, alert will pop up

    @IBAction func bringUpAlert(_ sender: Any) {
        let alert = UIAlertController(title: "Profile Photo", message: nil, preferredStyle: .actionSheet)
        alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action) -> Void in
            func showCamera(){
                let camera = UIImagePickerController()
                UIImagePickerController.isSourceTypeAvailable(.camera)
                camera.delegate = self
                camera.sourceType = .camera
                self.present(camera, animated: true, completion: nil)
            }
        }))

        alert.addAction(UIAlertAction(title: "Library", style: .default, handler: {(action) -> Void in
            func showLibrary(){
                if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
                    let library = UIImagePickerController()
                    library.delegate = self
                    library.sourceType = .photoLibrary
                    library.modalPresentationStyle = UIModalPresentationStyle.popover
                    self.present(library, animated: true, completion: nil)
                }
                func imagePickerController(_picker: UIImagePickerController, didFinishPickingMediaWithInfo: [String:Any]) {
                    let selectedImage = didFinishPickingMediaWithInfo[UIImagePickerControllerOriginalImage] as! UIImage
                    self.ProfilePic.setImage(selectedImage, for: .normal)
                }
            }
        }))

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

    override func viewDidLoad() {
        super.viewDidLoad()

        //Customizing Profile Pic View
        ProfilePic.layer.cornerRadius = ProfilePic.frame.size.width / 2
        ProfilePic.clipsToBounds = true
        ProfilePic.layer.borderWidth = 3
        ProfilePic.layer.borderColor = UIColor.gray.cgColor
    }
}

Upvotes: 0

Views: 310

Answers (2)

rmaddy
rmaddy

Reputation: 318804

The image picker is never shown. In the action alert, the function showCamera is never called.

The solution is to remove the function.

alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action) -> Void in
    let camera = UIImagePickerController()
    UIImagePickerController.isSourceTypeAvailable(.camera)
    camera.delegate = self
    camera.sourceType = .camera
    self.present(camera, animated: true, completion: nil)
}))

Or, move the showCamera function declaration outside and call it from the alert action.

func showCamera(){
    if UIImagePickerController.isSourceTypeAvailable(.camera) {
        let camera = UIImagePickerController()
        camera.delegate = self
        camera.sourceType = .camera
        self.present(camera, animated: true, completion: nil)
    }
}

alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action) -> Void in
    showCamera()
}))

The same is needed of the embedded showLibrary function. And the image picker delegate method also needs to be moved to the top-level of the class.

Final class:

class SignupViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    @IBOutlet weak var ProfilePic: UIButton!

    //When button is pressed, alert will pop up

    @IBAction func bringUpAlert(_ sender: Any) {
        let alert = UIAlertController(title: "Profile Photo", message: nil, preferredStyle: .actionSheet)
        alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: {(action) -> Void in
            self.showCamera()
        }))

        alert.addAction(UIAlertAction(title: "Library", style: .default, handler: {(action) -> Void in
            self.showLibrary()
        }))

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

    func showCamera(){
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            let camera = UIImagePickerController()
            camera.delegate = self
            camera.sourceType = .camera
            self.present(camera, animated: true, completion: nil)
        }
    }

    func showLibrary(){
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
            let library = UIImagePickerController()
            library.delegate = self
            library.sourceType = .photoLibrary
            library.modalPresentationStyle = UIModalPresentationStyle.popover
            self.present(library, animated: true, completion: nil)

        }
    }

    func imagePickerController(_picker: UIImagePickerController, didFinishPickingMediaWithInfo: [String:Any]) {
        let selectedImage = didFinishPickingMediaWithInfo[UIImagePickerControllerOriginalImage] as! UIImage
        self.ProfilePic.setImage(selectedImage, for: .normal)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        //Customizing Profile Pic View
        ProfilePic.layer.cornerRadius = ProfilePic.frame.size.width / 2
        ProfilePic.clipsToBounds = true
        ProfilePic.layer.borderWidth = 3
        ProfilePic.layer.borderColor = UIColor.gray.cgColor
    }
}

Upvotes: 1

7stud
7stud

Reputation: 48599

Example 1:

func doStuff(x: Int, handler: (Int) -> Void) {
        handler(x)
}

doStuff(x: 3) {val in
    print(val)
}

--output:--
3

Example 2:

func doStuff(x: Int, handler: (Int) -> Void) {
        handler(x)
}

doStuff(x: 3) {val in
    func calc(a: Int, b: Int) {
        print(a + b)
    }
}

--output:--
<Nothing>

iOS programming isn't really for beginning programmers--it's hard for experienced programmers.

Upvotes: 0

Related Questions