Search code examples
arraysswiftdictionaryuipickerview

How to Load a Dictionary into a UIPickerView


How can I load data from a dictionary into a PickerView in Swift?

I have dictionary with a String key (States) and a Double value (taxes) and what I want to do is be able to set the keys as the titleForRow of the UIPickerView and show the value of the selected key in a textField.

// Ideal Dictionary
private var states:[String:Double] = ["Alabama":6.000, "Illinois":7.000, "Oregon":8.000, "Wisconsin":9.000]

I was able to do what I described above using two arrays, one for the states and one for the taxes but I refuse to think that loading from a dictionary is not possible.

Here is what I currently have that works but using two arrays.

// Arrays
private var stateName = ["Alabama", "Illinois", "Oregon", "Wisconsin"]
private var stateTax = ["6.000", "7.000", "8.000", "9.000"]

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return stateName.count
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    inputTaxRate.text = stateTax[row]
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return stateName[row]
}

Any suggestion to improve the above code?


Solution

  • Dictionaries are unordered, so you are better off using an array. You can use an array of named tuples to keep your data together in one array:

    let stateInfo:[(name: String, tax: Double)] = [("Alabama", 6.000), ("Illinois", 7.000), ("Oregon", 8.000), ("Wisconsin", 9.000)]
    
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return stateInfo.count
    }
    
    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        inputTaxRate.text = stateInfo[row].tax
    }
    
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return stateInfo[row].name
    }