Reputation: 1
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
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
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