Led Led - 2 months ago 18
Swift Question

Swift - Cascading Pickers

Assuming I have 3 pickers with the following content:

Restaurant{
[Menu]
name
}

Menu{
[Ingredients]
time
}

Ingredients{
...
}


how can i implement a picker that updates automatically if the objects changes? (e.g. when the restaurant is picked, its menu and ingredients changes, when menu is picked the ingredients changes)

Answer Source

You can do something like this:

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate
{
    @IBOutlet weak var restaurantsPicker: UIPickerView!
    @IBOutlet weak var menuPicker: UIPickerView!
    @IBOutlet weak var ingredientsPicker: UIPickerView!

    var restaurants = ["R1", "R2", "R3"]

    var menus = ["R1": ["M1", "M2"],
                "R2": ["M2"],
                "R3": ["M1", "M3"]]

    var ingredients = ["M1":["I1", "I2", "I3"],
                       "M2":["I1", "I3"],
                       "M3":["I2", "I3"]]


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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
    {
        if pickerView === restaurantsPicker
        {
            return restaurants.count
        }
        else if pickerView === menuPicker
        {
            let restaurant = restaurants[restaurantsPicker.selectedRow(inComponent: 0)]
            return menus[restaurant]!.count
        }
        else
        {
            let restaurant = restaurants[restaurantsPicker.selectedRow(inComponent: 0)]
            let menu = menus[restaurant]![menuPicker.selectedRow(inComponent: 0)]
            return ingredients[menu]!.count
        }
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
    {
        if pickerView === restaurantsPicker
        {
            return restaurants[row]
        }
        else if pickerView === menuPicker
        {
            let restaurant = restaurants[restaurantsPicker.selectedRow(inComponent: 0)]
            return menus[restaurant]?[row]
        }
        else
        {
            let restaurant = restaurants[restaurantsPicker.selectedRow(inComponent: 0)]
            let menu = menus[restaurant]![menuPicker.selectedRow(inComponent: 0)]
            return ingredients[menu]?[row]
        }
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
    {
        if pickerView === restaurantsPicker
        {
            menuPicker.reloadComponent(0)
            ingredientsPicker.reloadComponent(0)
        }
        else if pickerView === menuPicker
        {
            ingredientsPicker.reloadComponent(0)
        }
    }
}

Screenshot:

enter image description here