FoodTracker Tutorial - Tap Gesture

So I'm having issues with the tap gesture for the "Work with View Controllers" section of the tutorial. I'm not getting the image picker to show up when i sumlate or run the app on an iPhone. I think the code is right, because its nearly identical to the sample. I've also rebuilt the app from the beginning of that section 4 or 5 times. I'm pretty sure the @IBOutlet and @IBAction are correctly connected because they have the filled grey circles next to them, but for some reason it won't work. However, I can correctly run the sample. Can anyone think of some issues that might be throwing me off?


import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

     // MARK: Properties


    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var mealNameLabel: UILabel!
    @IBOutlet weak var photoImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Handle the text field’s user input through delegate callbacks.
          nameTextField.delegate = self
    }


// MARK: UITextFieldDelegate
    func textFieldShouldReturn(textField: UITextField) -> Bool {

          // Hide the keyboard.

        textField.resignFirstResponder()
        return true
    }

    func textFieldDidEndEditing(textField: UITextField) {
        mealNameLabel.text = textField.text
    }


    // MARK: UIImagePickerControllerDelegate
    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
          // Dismiss the picker if the user canceled.
           dismissViewControllerAnimated(true, completion: nil)
    }

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

          // The info dictionary contains multiple representations of the image, and this uses the original.
          let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
          // Set photoImageView to display the selected image.
           photoImageView.image = selectedImage
          // Dismiss the picker.
          dismissViewControllerAnimated(true, completion: nil)
    }


     // MARK: Actions
     @IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {

          // Hide the keyboard.
          nameTextField.resignFirstResponder()
          // UIImagePickerController is a view controller that lets a user pick media from their photo library.
          let imagePickerController = UIImagePickerController()
          // Only allow photos to be picked, not taken.
          imagePickerController.sourceType = .PhotoLibrary
          // Make sure ViewController is notified when the user picks an image.
          imagePickerController.delegate = self
          presentViewController(imagePickerController, animated: true, completion: nil)
    }

    @IBAction func setDefaultLabelText(sender: UIButton) {
        mealNameLabel.text = "Default Text"
    }

}

Replies

Just working through this now, and found that depending what I dropped the UITapGestureRecognizer on it would either work on not. Directly connecting it to the image didn't seem to work. Connecting it to the ViewController seemed to make it work, but then it pops up if I click randomly around the window. Looks like there are some other posts referencing this below, going to have a look...

Found this output at the bottom of my screen, which was helpful. But now I wonder if there's a way to reassign which view the gesture recognizer is connected to?


2015-11-10 22:42:33.131 Foodtracker[26578:3111946] WARNING: A Gesture recognizer (<UITapGestureRecognizer: 0x7fbb30c1be70; state = Possible; view = <UIImageView 0x7fbb30c25060>; target= <(action=selectImageFromPhotoLibrary:, target=<Foodtracker.ViewController 0x7fbb30c1c7d0>)>>) was setup in a storyboard/xib to be added to more than one view (-><UIImageView: 0x7fbb30c25060; frame = (0 117; 320 320); autoresize = RM+BM; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x7fbb30f33260>; layer = <CALayer: 0x7fbb30c22190>>) at a time, this was never allowed, and is now enforced. Beginning with iOS 9.0 it will be put in the first view it is loaded into.

Found it - use the connections inspector for the UITapGestureRecognizer to delete all the connections I had created by dragging and dropping the control on to all my views and elements - basically clean that up and make it so that it is only connected to my image. Then I did a test - drop it on the stack and see if it works. Well it did. So then I move the connection over to the image. It doesn't work. So then I look at the attributes inspector for the image element itself, and check the box 'user interaction enabled' which had been unchecked. Ta Da! it works perfectly.

Actually for me it was just the checkbox issue. 'user interaction enabled' check box was not mentioned in the toturial or I missed it. Thx a lot!

Yeah, this is the solution. Thanks.

Thanks for this - I had also hit a wall in the tut. Also in case it helps anyone else, you may need need to create another connection between the Tap Gesture Recognizer and the image itself - - after you have created your initial @IBActions etc ( at least that worked for me). This 'extra' step seems to be either missing from the tut text - or the connections between methods and delegates just got messed up for me, basically having my 'Outlet collection' and 'Referencing Outlets' also set up properly on the image used as the Photo picker , worked for me as well as having User interaction enabled.