The_Ogre
The_Ogre

Reputation: 117

TableView gets populated with incorrect data

I have three view controllers each with a table view. In the first VC's tableV are names of continents, on selecting any continent name a user is taken to a VC with a tableview that has been populated by names of countries from selected continent. Selecting any country's name takes one to a third VC with a tableview that gets populated by provinces from the said country in this case the selected country's fragmented name as the provinces e.g if one selects Germany then the provinces in it are: {"Ger","ma","ny"} .The first and the second tableviews work fine but the third one only gets populated by data correctly when user follows through from the first element of the first table view (Europe) as indicated in these pictures: image of first tableview

image of second tableview when first item on 1st tableview is selected

image of 3rd tableV when 1st element on 2nd tableV is selected

On selecting any other element on the first table view (e.g North America), the 2nd tableview gets populated by data correctly but the third tableview each time gets populated by data as though I selected elements of the 2nd tableview populated by selecting first element on the first tableview (Europe) as in these pics: image of 2nd tableview on selecting 4th element from first tableV, image of 3rd table view with incorrect data

Here is my code responsible for first table view:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var TableView: UITableView!

    var continentData = ["Europe", "Asia", "Africa", "North America", "South America", "Australia"]


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return continentData.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "continentCell", for: indexPath)
        cell.textLabel?.text = continentData[indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let countryVC = CountryVC()
        countryVC.customInit(continentIndex: indexPath.row, title: continentData[indexPath.row])
        self.navigationController?.pushViewController(countryVC, animated: true)
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

Code responsible for second tableView:

import UIKit

class CountryVC: UIViewController,UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!


    let countryData = [

        ["Germany", "France", "Italy", "Spain","Sweden"],
        ["Thailand", "Singapore", "China", "Philippines", "Japan"],
        ["Zambia", "Egypt", "Kenya", "Nigeria", "Morocco"],
        ["Canada", "USA", "Mexico", "Jamaica", "Dominica"],
        ["Argentina", "Peru", "Colombia", "Brazil", "Chile"],
        ["Australia", "New Zealand", "Fiji", "Solomon Islands"]

    ]

    var continentIndex: Int!


    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.dataSource = self
        self.tableView.delegate = self

        let nib = UINib(nibName:"CountryCell", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "countryCell")

        // Do any additional setup after loading the view.
    }
    func customInit(continentIndex: Int, title: String){
        self.continentIndex=continentIndex
        self.title=title

    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return countryData[continentIndex].count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "countryCell", for: indexPath) as! CountryCell
        cell.textLabel?.text = countryData[continentIndex][indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let provinceVC = ProvinceVC()
        provinceVC.customInit(countryIndex: indexPath.row, title: countryData[continentIndex][indexPath.row])
        self.navigationController?.pushViewController(provinceVC, animated: true)
        tableView.deselectRow(at: indexPath, animated: true)

    }
}

And here is the code in it data to be populated in 3rd VC's table view appropriately:

import UIKit

class ProvinceVC: UIViewController, UITableViewDataSource,UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    let provinceData = [

        ["Ger","ma","ny"], ["Fr","a","nce"], ["Ita","ly"], ["Spa","in"], ["Swe","den"],
        ["Tha","il","and"], ["Si","nga","po","re"], ["Chi","na"], ["Phi","li","pp","ines"], ["Ja","pan"],
        ["Za","mb","ia"], ["Egy","pt"], ["Ke","nya"], ["Ni","ge","ria"], ["Mo","ro","cco"],
        ["Ca","na","da"], ["USA"], ["Me","xi","co"], ["Ja","ma","ica"], ["Do","mi","ni","ca"],
        ["Ar","ge","nt","ina"], ["Pe","ru"], ["Co","lo","mb","ia"], ["Bra","zil"], ["Chi","le"],
        ["Au","st","ra","lia"], ["New","Zea","la","nd"],["Fi","ji"], ["So","lo","mon","Is","la","nds"]

    ]

    var countryIndex: Int!


    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.dataSource = self
        self.tableView.delegate = self

        let nib = UINib(nibName:"ProvinceCell", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "provinceCell")

        // Do any additional setup after loading the view.
    }

    func customInit(countryIndex: Int, title: String){
        self.countryIndex=countryIndex
        self.title=title

    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return provinceData[countryIndex].count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "provinceCell", for: indexPath) as! ProvinceCell
        cell.textLabel?.text = provinceData[countryIndex][indexPath.row]
        return cell
    }


}

I also need to mention that because using real province names would be too ambiguous I decided to fragment the country names, these fragmented names represent the provinces.

What could be the issue in my code? And is there a better way of doing it?

Upvotes: 0

Views: 65

Answers (1)

Crazyrems
Crazyrems

Reputation: 2591

You don't carry the continent to the third view controller. You know the country of the continent but not the continent itself when entering the 3rd view controller.

There's also an inconsistency in your data structures.

  • Your first controller have an array of one dimension (array containing strings).
  • Your second controller is one step deeper, you have a two dimensions array (array containing arrays of string)
  • Your third controller is another step further, but you still have a two dimensions array, is should be a three dimensions array (an array containing arrays of arrays of strings)

You have to pass the continent to the third controller and/or find a better way to store and access your data.

Upvotes: 1

Related Questions