can't get label to show data from both UIpickers

I have created an array with two UIPickerviews, and I am trying to make the label display both of what have been picked. The first picker is plane manufacter, second label is plane model. I can get the plane manufacter to print on the label but not the models...


func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

if component == 0 {

aircraftType.reloadComponent(1)

selectedAircraft.text = aircraft[row]

}

}


This code above is working, but I want models to display as well as aircraft and when I put models in place of aircraft I get fatal error message "Cannot subscript a value of type '[String : [String]]' with an index of type 'Int'"

Accepted Reply

You can use func selectedRow(inComponent: Int) -> Int


I propose to do as follows:


define a func to update label


func updateLabel() {

     var aircraftFullName = ""
     let manuf = aircraftType.selectedRow(inComponent: 0)
     let model = aircraftType.selectedRow(inComponent: 1)
     if manuf < aircraft.count {
          aircraftFullName = aircraft[manuf]
          if let aircraftModels =  models[aircraftFullName] {
               if model < aircraftModels.count {
                    aircraftFullName = aircraftFullName + " - " + aircraftModels[model]
               }
          }
     }
     selectedAircraft.text = aircraftFullName
}

Call this where needed, such as in viewDidLoad and in didSelectRow:


    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 0 {
            aircraftType.reloadComponent(1)
            // selectedAircraft.text = aircraft[row]
        }
        updateLabel()
    }


Off topic:

you should add A340, maybe A310 and B707 as well as B737 ; maybe B717, the former Douglas DC9

Replies

There are several points you should explain:

I am trying to make the label display both of what have been picked.

Which label is it ? selectedAircraft ?


Have you 2 pickers or 1 picker with 2 components (usually simpler).


If you have 2 pickers

  @IBOutlet weak var manufacturerPicker: UIPickerView!
    @IBOutlet weak var planePicker: UIPickerView!


then, in

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { }


you need to test which has been selected (the simplest is to set a tag for each picker)


Where do you get the error (is it in the code below ? which line)

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 0 {
            aircraftType.reloadComponent(1)
            selectedAircraft.text = aircraft[row]
        }
    }

Claude -


I have one picker with two options... Here is all the code:


@IBOutlet weak var aircraftType: UIPickerView!

@IBOutlet weak var selectedAircraft: UILabel!

let aircraft = ["Airbus", "Boeing", "Bombardier", "Embraer"]

let models = [ "Airbus": ["A300", "A320", "A330", "A350", "A380"], "Boeing": ["B737", "B747", "B757", "767", "777", "787"], "Bombardier": ["CRJ200", "CRJ700/900"], "Embraer": ["ERJ145", "ERJ170", "ERJ190"] ]

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

if component == 0 {

return aircraft.count

}

else {

return (models[aircraft[aircraftType.selectedRow(inComponent: 0)]]?.count)!

}

}

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

return 2

}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

if component == 0 {

return aircraft [row]

}

else {

return models[aircraft[aircraftType.selectedRow(inComponent: 0)]]?[row]

}

}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

if component == 0 {

aircraftType.reloadComponent(1)

selectedAircraft.text = aircraft[row]

}

}


the label "selected aircraft" I am trying to get it to display both "aircraft" and "models" but it will only let me display aircraft. Any ideas?

You can use func selectedRow(inComponent: Int) -> Int


I propose to do as follows:


define a func to update label


func updateLabel() {

     var aircraftFullName = ""
     let manuf = aircraftType.selectedRow(inComponent: 0)
     let model = aircraftType.selectedRow(inComponent: 1)
     if manuf < aircraft.count {
          aircraftFullName = aircraft[manuf]
          if let aircraftModels =  models[aircraftFullName] {
               if model < aircraftModels.count {
                    aircraftFullName = aircraftFullName + " - " + aircraftModels[model]
               }
          }
     }
     selectedAircraft.text = aircraftFullName
}

Call this where needed, such as in viewDidLoad and in didSelectRow:


    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 0 {
            aircraftType.reloadComponent(1)
            // selectedAircraft.text = aircraft[row]
        }
        updateLabel()
    }


Off topic:

you should add A340, maybe A310 and B707 as well as B737 ; maybe B717, the former Douglas DC9

@claude31 That worked, thank you... I am still struggling to learn but after reading your code it makes sense. I need to keep doing my online course so I am able to formulate those ideas like you did. As for your off topic comment: Yes there are more aircraft to add, I was just throwing in a few so I didn't overwhelm myself. I fly the 747, so I wouldn't ever leave out another 4 engine aircraft like the A340, and based on your location, Im sure youre aware of the new A220... that will be interesting to see. If you have any aviation questions, please let me know if I can help you in any way. Merci.

Great. Flying 747, what a dream !


On which airline do you fly ?

I dont really want to put that on here, but feel free to e mail me and I would be happy to tell you.

I do understand and think you’reright.


good flights !