Swift 4: UIImagePicker delegate methods not being called - ios

I have a UIImageView that has my "profile image" inside. When I tap on this, it calls a function that presents my UIImagePickerController. This works fine. My issue is that my delegate methods simple aren't being called. When I add breakpoints, it doesn't hit them at all. I have used the exact same method elsewhere in my project and it works fine so there's nothing wrong with my info.plist file. Does anybody know what I'm doing wrong? Thank you...
extension ChatLogController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
profileImageView.image = image
self.dismiss(animated: true, completion: nil)
}
#objc func handlePresentImagePicker() {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
}

I realised that the issue was that I was using a custom transition (a transition that involved me being able to swipe right to dismiss my controller). Once I commented all of the code related to that, everything worked fine. Very unfortunate that I have to get rid of my transition but hey, it now works!

Related

One UIImagePickerController for multiple ImageVIews

could you please help me with UIImagePickerController
I have 12 ImageViews in 1 ViewController. I need help so that each ImageView could pick different photos from Library. Someone told me to use Tags for them but I can't make it work cause i'm new in Swift.
Enable User Interaction Enabled for each UIImageView on a Storyboard.
Add TapGestureRecogniser to each UIImageView. Connect each TapGestureRecogniser with IBAction.
#IBAction func tap(_ sender: UITapGestureRecognizer) {
currentImageView = sender.view as! UIImageView
let picker = UIImagePickerController()
picker.delegate = self
self.present(picker, animated: true, completion: nil)
}
Define variable to store current UIImageView
private var currentImageView: UIImageView? = nil
Handle image selection and assign the image to currentImageView
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage]
currentImageView?.image = image as! UIImage
self.dismiss(animated: true, completion: nil)
}
It's not about the swift. You set up a "tag" number in the Interface builder (or in the code. There is a .tag property on the UIResponder descendants).
After that you make a switch in your callback method like
To make it a bit clearer:
let picker: UIImagePicker! = {
// setup your image picker here, don't forget to set the proper delegate
}()
var lastSender: AnyObject?
func onTouch(_ sender: AnyObject?) {
// add checks for the sender here
lastSender = sender
present(picker, animated: true, completion: *Your Completion*)
}
Delegate:
in
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
let image = *Get Image From Info*
lastSender?.image = image

UIImagePickerController to import Image

i want import image in ios from library but i have error
value of type 'viewcontroller' has no member 'present'
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Alert(sender: AnyObject) {
let nextController = UIImagePickerController()
self.present(nextController, animated: true, completion: nil)
}}
Here's my stripped working code. I use two pickers - one for camera, one for library - because of some odd iOS bug with tint color. To avoid "massive view controller" issues, I tend to move everything possible related to a a UIImagePickerController into a separate file and extension.
class OpenViewController: UIViewController {
let pickerLibrary = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
pickerLibrary.delegate = self
}
}
extension OpenViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#objc func showImagePicker() {
pickerLibrary.allowsEditing = false
pickerLibrary.sourceType = .photoLibrary
present(pickerLibrary,
animated: true,
completion: nil)
pickerLibrary.popoverPresentationController?.sourceView = self.view
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: false, completion: nil)
}
}
While the present code looks correct, I notice several things you didn't post in your code. Maybe because you just didn't post it, but I would definitely check these things:
Are you setting ViewController to be a delegate?
Are you setting ViewController.view to be the source view? This may not be needed for iPhone, but definite helps with iPad.
Have you includes everything needed to be working for UIImagePickerControllerDelegate, UINavigationControllerDelegate?
Now as your error suggests, something else is likely the issue - a UIViewController can present another view controller. In this case you've given us no way to duplicate that error. In other words, I'm assuming that (1) You are seeing a UIButton attached to Alert() - BTW, Swift conventions use lower case for that - and (2) You've proven that when that button is tapped, `Alert() is actually executed.

Attempting to use photo Library on UICollectionViewCell Class

So right now I am trying to get the collection view Cells to use the photo library to update photos. Here is my code:
import UIKit
class viewCellVC: UICollectionViewCell, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var bookImage: UIImageView!
#IBAction func addImage(_ sender: Any) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
imagePicker.allowsEditing = false
self.window?.rootViewController?.present(imagePicker, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
bookImage.image = image
picker.dismiss(animated: true, completion: nil)
}
}
However, when I attempt to run the code and update the pictures, the simulator fails to open the photo library and I instead get the following error message(doesn't end the app, just fails to run the photo library):
2017-08-07 21:35:31.709183-0500 ChuBookElf[2817:66569] Warning: Attempt to present <UIImagePickerController: 0x7f907e0bf800> on <ChuBookElf.ViewController: 0x7f907de072c0> whose view is not in the window hierarchy!
Can somebody tell my what I am doing wrong? I've been on this for hours now.
For Reference, here is what the collection view cell looks like
For starters, you are creating the imagePicker in a UICollectionViewCell.
You should create the imagePicker in the ViewController that contains the said UICollectionView along with the delegate methods. Then, in didFinishPickingMediaWithInfo, set the selected image to the appropriate collectionViewCell and reload your collectionView

Swift ImagePicker inside NavigationController

So I am inside a navigation controller and would like to present an image picker upon a button press. That works fine, but when I dismiss the picker it throws me back to the root view controller, and not where I want to process the image.
This is my code:
#IBAction func attachPhotoButtonPressed(sender: UIButton) {
imagePicker.sourceType = .SavedPhotosAlbum
presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
print("Success")
} else{
print("Something went wrong")
}
self.dismissViewControllerAnimated(true, completion: nil)
}
I already looked at these questions, but didn't find a fix. (Not an objective-C guy)
Pushing a navigation controller is not supported- performing segues
presenting ViewController with NavigationViewController swift
Pushing a navigation controller is not supported
The reason that you're bouncing to the root view controller is because this line
self.dismissViewControllerAnimated(true, completion: nil)
is dismissing the parent view (self), and not the picker view. So assuming that you have a reference to your picker, then you should be calling
picker.dismissViewControllerAnimated(true, completion: nil)
I just had the same problem as you and I'm doing this as an alternative :
// Custom class : see below.
private let imagePicker = ImagePickerViewCustomController()
#IBAction func openPicker(_ sender: Any) {
// Hide the navigation bar when the picker is opened
navigationController!.setNavigationBarHidden(true, animated: false)
// Add it as a subview
addChild(imagePicker)
view.addSubview(imagePicker.view)
}
I have a subclass of UIImagePickerController that hides the status bar.
The content of the scrollView in the picker scroll over the status bar otherwise.
class ImagePickerViewCustomController: UIImagePickerController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.isStatusBarHidden = true
}
}
And finally handle delegate methods by dismissing the picker by this way :
extension UIViewController : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){
dismissPicker(picker: picker)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismissPicker(picker: picker)
}
private func dismissPicker(picker : UIImagePickerController){
picker.view!.removeFromSuperview()
picker.removeFromParent()
navigationController?.setNavigationBarHidden(false, animated: false)
UIApplication.shared.isStatusBarHidden = false
}
}

Selecting photo returns to blank UI

I am trying to make an image uploader on my ios app.
EDIT 7
This question is now more clearly asked here: Present Modal for Image Select Erases UI
END OF EDIT 7
The first thing I am trying to do is enable the user to select an image that they want for upload.
EDIT 6
I have simplified all the code to simply one button press. The Modal presentation deletes the previous page's UI. How I prevent this.
import UIKit
class AddImageToStandViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func loadImageButtonTapped(sender: UIButton) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
I have found that the selection works just fine and does not destroy the UI if I push/segue from a different to this controller.
END OF EDIT 6
Below this is the other methods that I have tried before this
So far, this code enables a user to press a button and choose a photo from their photos. But, after they click the photo it just returns them to an empty View except the navbar at the bottom.
It seems my user is being returned, not to the view that they came from, but to a separate empty view. How do I return the user to the view that they came from?
import UIKit
class CreateStandViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var image: UIImageView!
...
#IBAction func selectPicture(sender: AnyObject) {
let ImagePicker = UIImagePickerController()
ImagePicker.delegate = self
ImagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(ImagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)
}
...
let me know if there is any more information that I should give.
EDIT 1
this code has the same effect
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
picker.dismissViewControllerAnimated(true, completion: nil)
}
I have tried adding this line below but I get an error stating that CreateStandViewController.Type cannot be converted to the expected UIViewController.
self.presentViewController(CreateStandViewController, animated: true, completion: nil)
EDIT 2
This code below doesnt error but also changes nothing
let createStandController = CreateStandViewController()
self.presentViewController(createStandController, animated: true, completion: nil)
EDIT 3
I have literally copied all the code from here: http://www.codingexplorer.com/choosing-images-with-uiimagepickercontroller-in-swift/ and now have:
import UIKit
class CreateStandViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
#IBAction func loadImageButtonTapped(sender: UIButton) {
imagePicker.allowsEditing = false
imagePicker.sourceType = .PhotoLibrary
presentViewController(imagePicker, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
// MARK: - UIImagePickerControllerDelegate Methods
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
dismissViewControllerAnimated(true, completion: nil)
}
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
}
This has the same issue as before. When the image is selected I am sent back to a view that is white with the navbar at the bottom.
EDIT 4
I have run the same code in its own separate project as a stand alone view controller and it works. There is some code that I have in the background of my app that is killing the functionality of the code (maybe). I am guessing it may have something to do with the navbar?
EDIT 5
I removed the tab bar at the bottom by seguing to the image selecting view via a present Modally segue, but it had no effect.
Just replace your
self.dismissViewControllerAnimated(true, completion: nil)
with
picker.dismissViewControllerAnimated(true, completion: nil)
I think you will get the point after that

Resources