Nicholas Richardson
Nicholas Richardson

Reputation: 55

Passing data from one TableView to another TableView

I have setup a prepare for segue method and I believe I have successfully sent my data to the second ViewController but I'm unsure how to use the passed data.

For Example:

Picture

When the user taps Protein I want to send to the second tableViewController protein was selected and then populate it with an array of protein.

Below is my first tableview code:

First TableView:

class OrdersTableViewController: UITableViewController {
        var titleList = ["Protein","Protein Flavor", "Base", "Base Flavor", "Side", "Additional"]

        // MARK: - Table view data source

        override func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }

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

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! OrdersTableViewCell

            cell.cellTitle.text = titleList[indexPath.row]

            // Configure the cell...

            return cell
        }

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if (segue.identifier == "showDetailView") {
                let DVC = segue.destination as! OrderDetailTableViewController

                if let indexpath = self.tableView.indexPathForSelectedRow {
                    let proteins = titleList[indexpath.row] as String
                    DVC.sentData1 = proteins

                    print (proteins)
                }
            }
        }
    }

Currently if I print the value that's being sent it seems to be working. In this case it prints "Protein". But ideally this is what I want, but I'm unsure how to do it.

class OrderDetailTableViewController: UITableViewController {
    var sentData1:String!
    var proteinList = ["Salmon", "Meatballs", "Chicken", "Cod","Sausage", "Frittata"]
    var baseList = ["White Rice", "Brown Rice"]

    //take what is selected from sentData1 and populate second tableview

    if sentData1 == "Protein" {
        //populate tableview with proteinList
    }

    if sentData1 == "Base" {
        //populate tableview with baseList
    }

All the posts I've found deal with a TableView sending data to a normal viewController which I haven't found useful when trying to implement it. I'm brand new to Swift so any tips are appreciated.

Upvotes: 1

Views: 2321

Answers (2)

Phillip Mills
Phillip Mills

Reputation: 31026

I suggest setting up a data structure to represent your information rather than multiple string arrays. Here's a simple example:

class Nutrient {
    var kind: String
    var examples: [String]

    init(_ kind: String, examples: [String] = []) {
        self.kind = kind
        self.examples = examples
    }
}

let dataModel = [Nutrient("Protein", examples:["Salmon", "Meatballs", "Chicken", "Cod","Sausage", "Frittata"]),
                 Nutrient("Base", examples:["White Rice", "Brown Rice"])]

With that, you would use the nutrient kind field to populate your first table and pass the nutrient examples array to your second table. The second table wouldn't need to know about anything except what it's given to display.

Upvotes: 2

Jacob Boyd
Jacob Boyd

Reputation: 680

It sounds like you are using a triggering your segue from a on tap in your storyboard, you could remove that trigger and simply have that segue point from one viewController to your second VC. Then add a didSelectCellAtIndexPath function:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //save the selectedIndex in a class variable
    selectedIndex = indexPath
    performSegueWithIdentifier("showDetailView", nil)
}

Then in your prepareForSegue:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "showDetailView") {
            let DVC = segue.destination as! OrderDetailTableViewController
            DVC.sentData1 = titleList[selectedIndex.row]
        }
    }

Then:

class OrderDetailTableViewController: UITableViewController {
    var sentData1:String!
    var secondTableViewDataSource : [String] = []
    var proteinList = ["Salmon", "Meatballs", "Chicken", "Cod","Sausage", "Frittata"]
    var baseList = ["White Rice", "Brown Rice"]

//take what is selected from sentData1 and populate second tableview
override func viewDidLoad(){
    super.viewDidLoad()
    switch sentData1 {
    case "Protein":
        secondTableViewDataSource = proteinList
        //you may need to call tableView.reloadData() here too
        break
    default:
        break
    }
}

*I wanted to add since I seen that your are using a UITableViewController while there is nothing wrong with that...using a UIViewController and subscribing to the UITableViewDataSource/Delegate protocols would allow much more flexibility. I hardly ever use actual UITableViewControllers

Upvotes: 2

Related Questions