1

I need a multiple component pickerview, but I need to add a new column to the far left of it. So far it only has two of the three I need. Here is the current code. I have addeded arrays, wrapped an array inside an array, added variables as a column and also changed the outputs.

import UIKit

class Country {
    var cats: String
    var country: String
    var cities: [String]

    init(country:String, cities:[String]) {
        self.cats = cat
        self.country = country
        self.cities = cities
    }
}

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    @IBOutlet weak var pickerView: UIPickerView!
    @IBOutlet weak var countryLbl: UILabel!

    var countries = [Country]()

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

        cats.apppend(Cat(cat: "furry",
        countries.append(Country(country: "India", cities: ["Delhi", "Ahmedabad", "Mumbai", "Pune"]))
        countries.append(Country(country: "USA", cities: ["New York", "DC", "Fairfax"]))
        countries.append(Country(country: "Austrailia", cities: ["Sydney", "Melbourne"]))

        super.viewDidLoad()
    }

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

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

        if component == 0 {
            return countries.count
        }
        else {
            let selectedCountry = pickerView.selectedRow(inComponent: 0)
            return countries[selectedCountry].cities.count
        }

    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == 0 {
            return countries[row].country
        }
        else {
            let selectedCountry = pickerView.selectedRow(inComponent: 0)
            return countries[selectedCountry].cities[row]
        }
    }

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

        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        let selectedCity = pickerView.selectedRow(inComponent: 1)
        let country = countries[selectedCountry].country
        let city = countries[selectedCountry].cities[selectedCity]

        countryLbl.text = "Country: \(country)\nCity: \(city)"

    }
}

I added the vars but do I add more brackets and then I don't know how to identify the self like why does country = country but cat can't = cat? Also, the first column I'm going to add (far left in the row) will only have 2 choices and won't effect the other choices.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
mrpotter
  • 17
  • 1
  • 8
  • What third column do you need? What is preventing you from adding the third column? – rmaddy Jan 16 '18 at 15:41
  • so theres two, but i need to add one at the beginning (making there 3 colunns total) the first one (the column i need) doesnt effect the other two is just a simple 2 choices answer – mrpotter Jan 16 '18 at 15:52
  • So what is stopping you from adding the new column? What have you tried? What issue are you having? – rmaddy Jan 16 '18 at 15:54
  • Yes, you need to update each of the picker view data source and delegate methods to work with the new component. Give it a try. Then update your question with your attempted code and explain what issues you are having. – rmaddy Jan 16 '18 at 15:59
  • Just explain what it is you want your picker view to do. Don't worry about what it does already. What it does already is irrelevant. What do you want it to do? – Fogmeister Jan 16 '18 at 16:37

1 Answers1

0

Since the cats component has nothing to do with the countries, do not add cats to your Countries class (which should be a struct, by the way).

Just have a separate cats array in your view controller. And you need to update all of the picker view methods.

struct Country {
    let country: String
    let cities: [String]
}

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    @IBOutlet weak var pickerView: UIPickerView!
    @IBOutlet weak var countryLbl: UILabel!

    let cats = ["Cat1", "Cat2"]    
    var countries = [Country]()

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

        countries.append(Country(country: "India", cities: ["Delhi", "Ahmedabad", "Mumbai", "Pune"]))
        countries.append(Country(country: "USA", cities: ["New York", "DC", "Fairfax"]))
        countries.append(Country(country: "Austrailia", cities: ["Sydney", "Melbourne"]))

        super.viewDidLoad()
    }

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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if component == 0 {
            return cats.count
        } else if component == 1 {
            return countries.count
        } else {
            let selectedCountry = pickerView.selectedRow(inComponent: 1)
            return countries[selectedCountry].cities.count
        }
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == 0 {
            return cats[row]
        } else if component == 1 {
            return countries[row].country
        } else {
            let selectedCountry = pickerView.selectedRow(inComponent: 1)
            return countries[selectedCountry].cities[row]
        }
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == 0 {
            // do something with the new cat
        } else if component == 1 || component == 2 {
            if component == 1 {
                pickerView.reloadComponent(2)
            }

            let selectedCountry = pickerView.selectedRow(inComponent: 1)
            let selectedCity = pickerView.selectedRow(inComponent: 2)
            let country = countries[selectedCountry].country
            let city = countries[selectedCountry].cities[selectedCity]

            countryLbl.text = "Country: \(country)\nCity: \(city)"
        }    
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • love u 2 the swift moon and back – mrpotter Jan 16 '18 at 16:42
  • wait this doesnt make sense. why did u add cat to that bottom code? wont that mess up the other two columns? starting at "func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { – mrpotter Jan 16 '18 at 17:02
  • Yes, it makes perfect sense. As I stated in several of my comments and clearly show in my answer, you have to update all of the picker view methods to work with all three components. Did you actually try my code as-is? My code will show three components in the picker view. The cat list will be in the first component. The country list in the middle component. And the city list in the last component. That is what you wanted, right? – rmaddy Jan 16 '18 at 17:27
  • That's a completely separate issue from this question. Indicate that this question is solved. If you need help with your new issue, please post a new question with all relevant details including the complete error. – rmaddy Jan 16 '18 at 17:52