Search code examples
swiftuipickerview

How do I send UIPickerView selected row to another ViewController


I would like to send the selected UIPickerViews row to another view controller. I have placed my UIPickerView didSelectRow inside of my prepare for segue function. However the selected strings are not going to my next View Controller. Could someone explain to me what I am doing wrong? I really appreciate it.

import UIKit

class LengthViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {


    @IBOutlet weak var lengthTextField: UITextField!
    @IBOutlet weak var lengthPickerView: UIPickerView!
    var startingUnit = ["","Feet","Inches","Nanometer","Millimeter","Meters","Kilometer","Yards","Miles"]
    var finalUnit  = ["","Feet","Inches","Nanometer","Millimeter","Meters","Kilometer","Yards","Miles"]
    var feet = Double()
    var inches = Double()
    var nanometer = Double()
    var millimeter = Double()
    var meters = Double()
    var kilometer = Double()
    var yards = Double()
    var miles = Double()

    override func viewDidLoad() {
        super.viewDidLoad()
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))
        view.addGestureRecognizer(tap)
        lengthPickerView.delegate = self
        lengthPickerView.dataSource = self
        lengthTextField.delegate = self

    }
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {


        guard let oldText = textField.text, let r = Range(range, in: oldText) else {

            return true
        }

        let newText = oldText.replacingCharacters(in: r, with: string)
        let isNumeric = newText.isEmpty || (Double(newText) != nil)
        let numberOfDots = newText.components(separatedBy: ".").count - 1

        let numberOfDecimalDigits: Int
        if let dotIndex = newText.firstIndex(of: ".") {
            numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
        } else {
            numberOfDecimalDigits = 0
        }

        return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 5
    }
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var label = UILabel()
        if let v = view as? UILabel { label = v }
        label.font = UIFont (name: "System", size: 20)
        label.textColor = UIColor.white
        label.text =  startingUnit[row]
        label.text = finalUnit[row]
        label.textAlignment = .center
        return label
    }
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 2
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if component == 0 {
            return startingUnit.count
        }else{
            return finalUnit.count
        }
    }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == 0 {
            return startingUnit[row]
        }else{
            return finalUnit[row]
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let lengthOutput = segue.destination as! LengthOutputViewController


    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 0 {
           lengthOutput.startingLength = startingUnit[row] //This is where i try to send to next view controller
        }
        if component == 1 {
            lengthOutput.endingLength = finalUnit[row] //This is where i try to send to next view controller
        }
    }

    }

    @IBAction func calculatePressed(_ sender: Any) {
        if lengthTextField == nil {
            createAlert(title: "Missing length value", message: "Enter value")
        }else{
            performSegue(withIdentifier: "lengthOuput", sender: nil)
        }
    }

    func createAlert (title: String, message: String){
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: { (Action) in
            alert.dismiss(animated: true, completion: nil)
        }))
        self.present(alert, animated: true, completion: nil)
    }

}

Solution

  • Your pickerview’s didSelectRow() should be defined at the top level of your Controller.

    When it gets invoked, store the value you want to pass to the other controller in an ivar and then in the prepare() you can assign that to a property of the other controller.