How do I use the updated UIImagePickerControllerDelegate iOS 12 API? - ios

How do I use the updated UIImagePickerControllerDelegate API since it changed to [UIIMagePickerController.InfoKey : Any]? This part has been updated. I also searched here and I could not find an answer.
import UIKit
class adicionarNovoItemVc: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var textFieldNome: UITextField!
let imagePicker = UIImagePickerController()
#IBOutlet weak var namePreview: UILabel!
#IBOutlet weak var imagePreview: UIImageView!
let picker = UIImagePickerController()
#IBAction func botaoAdcFoto(_ sender: UIButton) {
picker.allowsEditing = true
picker.delegate = self
present(picker, animated: true)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
???
}
}
Update:
After updating the didFinishPickingMediaWithInfo delegate to :
private func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[.originalImage] as! UIImage? {
self.imagePreview.image = image
self.picker.dismiss(animated: true, completion: nil)
}
}
I now get:
Cannot downcast from 'Slice>' to a more optional type 'UIImage?'

It's not really much different. In iOS 12, lots of the old constants names have been refactored.
Instead of the old key UIImagePickerControllerOriginalImage you now use UIImagePickerController.InfoKey.originalImage:
Something like:
let image = info[UIImagePickerControllerOriginalImage]
now becomes:
let image = info[.originalImage]
See the related documentation for UIImagePickerController.InfoKey.
Update:
You made several mistakes in your attempted didFinishPickingMediaWithInfo. You need:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.originalImage] as? UIImage {
self.imagePreview.image = image
}
self.picker.dismiss(animated: true, completion: nil)
}

You need to set the mediaTypes of the picker using the availableMediaTypes class func of UIImagePickerController and retrieve the actual image from the info parameter.
#IBAction func botaoAdcFoto(_ sender: UIButton) {
picker.allowsEditing = true
picker.delegate = self
picker.sourceType = .photoLibrary
if let mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary) {
picker.mediaTypes = mediaTypes
}
present(picker, animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as! UIImage? {
self. imagePreview.setImage(image, for: .normal)
self.picker.dismiss(animated: true, completion: nil)
}
}

Related

Image not showing up in ImageView after using Image Picker

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)
}

UIImage is not showing after selecting image from gallery or camera

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)
}

UIImageView not updating with new image after picture taken or picture chosen from photo library

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.

Swift - ImagePicker not executing delegate

I just want to display an image taken with the iPhone camera in a ImageView. That was the first step of the project but it doesn't work...
Here is my code :
import UIKit
import MobileCoreServices
class ViewController: UIViewController,UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var scanButton: UIButton!
#IBOutlet weak var textfield: UITextField!
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.imagePicker.modalPresentationStyle = UIModalPresentationStyle.currentContext
self.imagePicker.delegate = self
self.imagePicker.mediaTypes = [kUTTypeImage as String]
self.imagePicker.sourceType = .camera
self.imagePicker.allowsEditing = true;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: - Actions
#IBAction func scanAction(_ sender: UIButton) {
print("----- scanAction -----");
self.present(self.imagePicker, animated: true, completion: nil)
}
//MARK: - UIImagePickerControllerDelegate
private func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
print("----- didFinishPickingMediaWithInfo -----");
var image:UIImage!;
if let pickedImage = info[UIImagePickerControllerEditedImage] as? UIImage {
image = pickedImage;
}
else {
image = info[UIImagePickerControllerOriginalImage] as! UIImage;
}
self.imageView.image = image;
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("----- imagePickerControllerDidCancel -----");
dismiss(animated: true, completion: nil)
}
}
I see the print of the action button but I never see the following one :
print("----- didFinishPickingMediaWithInfo -----");
I already have done imagePicker like this in the past so I don't understand why it doesn't work.
Can someone help me please?
The type of info is changed to [String : Any] in Swift 3 instead of [String : AnyObject] also you have not added _ as first parameter label, so change your method like this.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print("----- imagePickerControllerDidCancel -----");
}

UIImagePickerController: didFinishPickingMediaWithInfo not being called

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
}

Resources