0

I am trying to pass the selection of UIPickerView as a string to a new ViewController, unfortunately when I do it is returning a nil value. I have been following a few different tutorials but I cannot seem to get it to work. Any suggestions would be appreciated.

class menu: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var pickerView: UIPickerView!
    @IBOutlet weak var newsButton: UIButton!

    var pickerDataSource = ["Canterbury-Bankstown Torch", "Auburn Review", "Inner West Times", "Seniors "];
    var chosenState = String()

    override func viewDidLoad() {
        super.viewDidLoad()
        pickerView.delegate = self
        pickerView.dataSource = self
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerDataSource.count;
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerDataSource[row] as String
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        chosenState = pickerDataSource[row]
    }

    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "customSegue" {
            if let secondViewController = segue.destination as? ViewController {
                secondViewController.chosenState = chosenState
            }
        }
    }

    @IBAction func newsButton(_ sender: Any) {
        self.performSegue(withIdentifier: "customSegue", sender: nil)
    }

New viewController contains:

    var chosenState: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        finalPublication?.text = chosenState
        print(chosenState) //Just so I can see if it works
}
Dimple
  • 788
  • 1
  • 11
  • 27
  • Try to debug and check if you are getting correct value in functions: pickerView:didSelectRow:inComponent & prepareForSegue. – OnkarK Oct 04 '18 at 06:04
  • 1
    Check if your execution reach at `secondViewController.chosenState = chosenState` point or not – Satish Oct 04 '18 at 06:06
  • 1
    Are you picking a value in the picker view? `didSelectRow` is only called when you move the picker view to a different row. – rmaddy Oct 04 '18 at 06:08
  • If I hard code secondViewController.chosenState = "test" for example I still receive a nil value but when I print didSelectRow it is returning what I choose but still not passing it on to the new ViewController. – user2869163 Oct 04 '18 at 06:11
  • Where is it returning `nil`? – Rakesha Shastri Oct 04 '18 at 06:11
  • After I tap on continue button and go to the new ViewController it is returning in the target output of xcode (sorry if my terminology with some of this isn't great, I am not a programmer). – user2869163 Oct 04 '18 at 06:13
  • Adding on to what @rmaddy said. You'd want to set the default value for `chosenState` as `pickerDataSource[0]` instead of an empty string. – Rakesha Shastri Oct 04 '18 at 06:15

2 Answers2

1

you are using the wrong method func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)

You should use this:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "customSegue" {
        if let secondViewController = segue.destination as? ViewController {
            secondViewController.chosenState = chosenState
        }
    }
}
Satish
  • 2,015
  • 1
  • 14
  • 22
  • Hi Satish, your suggestion works perfectly (THANKYOU!) after selecting an item in the UIPickerView, any suggestion on how to also pass the initial selection on load. (For example the default selection)? – user2869163 Oct 04 '18 at 06:19
  • @user2869163 read the comments. It has already been explained. – Rakesha Shastri Oct 04 '18 at 06:34
0

You need to override prepare for segue so that prepareForSegue will call and you get your selected value in second controller.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "customSegue" {
        if let secondViewController = segue.destination as? ViewController1 {
            secondViewController.chosenState = chosenState
        }
    }
}
Denis
  • 492
  • 2
  • 15