I am starting from zero with iOS app development but I need to create an app that can use the iPhone camera to take an image. I have found UIImagePickerController but I cannot figure out how to implement it correctly. If anyone could help me that would be great. Also I know very little about app development so if there is any background knowledge I would need to understand your answers would be appreciated.
You can call this method wherever you want to open UIImagePickerController:
func openImagePicker() {
let vc = UIImagePickerController()
vc.sourceType = .camera
vc.allowsEditing = true
vc.delegate = self
present(vc, animated: true)
}
Make your view controller conform to both UINavigationControllerDelegate and UIImagePickerControllerDelegate by making an extension like this:
extension youViewControllerClass: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true) // dismisses camera controller
guard let image = info[.editedImage] as? UIImage else {
print("No image found")
return
}
// You will get your image here
print(image.size)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController){
picker.dismiss(animated: true, completion: nil)
// here you will get the cancel event
}
}
Related
I am trying to write a simple app that will update the ImageView with a photo from my photos library. I can open the photos library and select a photo, but after I do that the default image in the ImageViewer does not show up. Any idea why?
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet weak var photoView: UIImageView!
#IBAction func testGesture(_ sender: UITapGestureRecognizer) {
let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
private func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let selectedImage = info[UIImagePickerController.InfoKey.originalImage.rawValue] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
photoView.image = selectedImage
dismiss(animated: true, completion: nil)
}
}
You're not using the UIImagePickerControllerDelegate's didFinishPickingMediaWithInfo method. Remove the private and modify the didFinishPickingMediaWithInfo method to the UIImagePickerControllerDelegate method syntax and you're good to go.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
photoView.image = selectedImage
print(selectedImage)
dismiss(animated: true, completion: nil)
}
I am trying to select image from camera or gallery and showing the selected image to the screen in my image view. But it's not showing.
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let selectedImage = info[.originalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
imageview.image = selectedImage
dismiss(animated: true, completion: nil)
}
What am I missing?
In my case the breakpoint function is not at all invoking
If your breakpoint function is not at invoking then I think you have not set the imagePicker delegate in viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
I faced same issue before and resolved it by setting image with delay like showed below:
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
self.imageview.image = selectedImage
})
Hope this will help.
Make sure you have UIImagePickerControllerDelegate added to your class and have set your UIImagePickerController instance delegate:
class PickerViewController: UIViewController, UIImagePickerControllerDelegate {
var pickerController = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
pickerController.delegate = self
}
}
Also, it's better to dismiss the picker parameter sent to this delegate:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
...
picker.dismiss(animated: true, completion: nil)
}
I presented UIImagePickerController() from ViewControllerA and when I select a image its delegate called and in that delegate I wrote
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
dismiss(animated: true, completion: nil)
}
but viewDidLoad() of ViewControllerA also called
Please find below code, viewDidLoad doesn't get called every time.
override func viewDidLoad() {
super.viewDidLoad()
print("View Did Load")
}
private func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject]) {
picker.dismiss(animated: true, completion: nil);
_ = info[UIImagePickerControllerOriginalImage] as! UIImage
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
Open Photo Library using this code,
#IBAction func btnclicked(_ sender: Any) {
let picker = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.delegate = self
self.present(picker, animated: true, completion: nil)
}
Also post some of your code so I can review it.
Let me know in case of any queries.
When using the UIImagePickerViewController, often times the camera will cause a memory warning and your viewcontroller's viewDidUnload method will be called. Next time your view is shown (when the UIImagePickerViewController is dismissed), the viewDidLoad method will be called because it was previously unloaded.
I'm trying to populate an image within a UIImageView after I either take a picture or choose a picture from my photo library.
here is the code handling the camera and photo library activations:
#IBAction func activateCmera(_ sender: Any) {
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
#IBAction func activatePhotoLib(_ sender: Any) {
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
Here is the code that populates the image within the UIImageView:
#IBOutlet weak var imageView: UIImageView!
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
self.imageView.contentMode = .scaleAspectFit
self.imageView.image = image
self.dismiss(animated: true, completion: nil);
}
currently after I take a picture with my camera or choose an image from my photo library, I'm redirected to the initial view of the app without UIImageView space updated with the photo.
Any help is appreciated thanks!
In Swift 3 you need permission to access photoLibrary by adding below keys to your plist and you need to use the proper delegate method.
Add UIImagePickerControllerDelegate& UINavigationControllerDelegate to your classand set imagePicker delegate to viewDidLoad & Try below code.
let imagePicker = UIImagePickerController()
#IBAction func activatePhotoLib(_ sender: UIButton) {
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary;
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.image = image
}
picker.dismiss(animated: true, completion: nil);
}
Output: updated
This seems to be a problem related to XCode failing to explain that the imagePickerController function syntax has changed (since Swift 3). You will find these two ways of writing the function all over the web. You will also be able to use both in XCode without getting any errors. But only the second one will actually get the image properly.
(Option 1 - doesn't work, but XCode doesn't flag it):
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { }
(Option 2 - this is the right syntax!):
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { }
**You need to save the UIImagePickerController like Global Object, after that, you need push this code on your action function
**
#objc func getImage() {
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = false
imagePicker.modalPresentationStyle = .overCurrentContext
present(imagePicker, animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.image = image
}
self.dismiss(animated: true, completion: nil);
}
I was having the same issue. Apparently the imagePickerController function has changed again since the last answer. I had to change the function a bit to work with Swift 5.4:
/ Doesn't work
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// Does work
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
The info parameter now expects a dictionary of UIImagePickerController InfoKeys.
Hope you're all doing well. Wondered if anyone could help me understand why Xcode fails to play nice with me....
I have broken the code into sections below in order to allow me to select a profile photo from UIImagePicker:
WORKS: Assigning the delegate class for both ImagePicker & NavigationController
WORKS: Instantiating the UIImagePicker variable
WORKS: Load ImagePickerViewController and enable to select an image
FAILS: Added additional functions for closing and finishing picking with a UIImagePicker but neither ever get called? What have I done wrong?
Thanks in advance!
class ProfileVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var imagePicker: UIImagePickerController!
override func viewDidLoad() {
super.viewDidLoad()
imagePicker = UIImagePickerController()
imagePicker.delegate = self
}
#IBAction func selectPhotoPressed(sender: UITapGestureRecognizer) {
if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {
self.imagePicker.sourceType = .PhotoLibrary
} else {
self.imagePicker.sourceType = .Camera
}
imagePicker.allowsEditing = true
imagePicker.mediaTypes = [kUTTypeImage as String]
self.presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo image: UIImage, editingInfo: [String : AnyObject]?) {
headerView.profilePhoto.contentMode = .ScaleAspectFill
headerView.profilePhoto.image = image
imagePicker.dismissViewControllerAnimated(true, completion: nil)
uploadImage(image)
}
OK I seem to have it working now, thanks for your help in identifying that the code was ancient ;) Here is what now runs:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let image = info[UIImagePickerControllerOriginalImage] as? UIImage
headerView.profilePhoto.contentMode = .ScaleAspectFit
headerView.profilePhoto.image = image
imagePicker.dismissViewControllerAnimated(true, completion: nil)
uploadImage(image!)
}
You have the signature wrong, but since it's an optional method, you are not getting warned. It should be:
func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// Your code
}
As everyone suggested, use the didfinishpickingmediawithinfo method and to extract the image in swift 5, iOS 13, use the info dictionary
func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject]) {
imageView.image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
}