I'm trying to create a UIBarButtonItem that opens the camera once the button has been tapped. For some reason, my takePicture(_sender:) function doesn't seem to be getting called.
I originally tried to create my UIBarButtonItem using the Interface Builder. Here was the interface and a screenshot of the actions connected to the UIBarButtonItem:


And here is the code for my takePicture(_sender:) function:
@IBAction func takePicture(_ sender: UIBarButtonItem) {
print("Taking picture...")
let imagePicker = UIImagePickerController()
// If the device has a camera, take a picture; otherwise,
// just pick from photo library
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
} else {
imagePicker.sourceType = .photoLibrary
}
imagePicker.delegate = self
// Place image picker on the screen
present(imagePicker, animated: true, completion: nil)
}
The little circle next to my function declaration is filled in and connected properly:

However, when I load the simulator and press the button, the UIImagePickerController never appears and my print() function is never called in the code.
So, I then tried to declare the UIBarButtonItem programmatically to see if perhaps it was an issue under-the-hood of Xcode's Interface Builder. Here was my code:
(Note: I deleted the UIBarButtonItem from the Interface Builder and then I connected the UIToolbar to my code using an @IBOutlet.)
override func viewDidLoad() {
super.viewDidLoad()
let takePictureBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.camera, target: self, action: #selector(DetailViewController.takePicture))
toolBar.setItems([takePictureBarButton], animated: false)
}
@objc func takePicture() {
print("Taking picture...")
let imagePicker = UIImagePickerController()
// If the device has a camera, take a picture; otherwise,
// just pick from photo library
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
} else {
imagePicker.sourceType = .photoLibrary
}
imagePicker.delegate = self
// Place image picker on the screen
present(imagePicker, animated: true, completion: nil)
}
As a last ditch attempt at debugging this program and trying to find where the problem lies, I created a temporary button in my UI and connected that to my takePicture(_sender:) function instead (I changed the signature from a UIBarButtonItem to a UIButton). That worked perfectly. This tells me that the problem is not with the function itself, but has something to do with the connection.
I was seconds away from posting this question when I found a similar question. The user stated that the root of their problem lied in a UITapGestureRecognizer on their View Controller.
To solve my problem, I simply set my UITapGestureRecognizer's target to be my StackView instead of the the entire view.
Original:

Resolved:

I'd be curious to learn why the UITapGestureRecognizer stopped my UIBarButtonItem from being tapped, but not the normal UIButton. Seems a little strange...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With