1

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.

rmaddy
  • 314,917
  • 42
  • 532
  • 579

2 Answers2

2

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.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • I agree, having an actual data structure would make your code base much better! – Jacob Boyd Oct 03 '17 at 18:14
  • where would I implement this to make it work? I like this idea – Nicholas Richardson Oct 03 '17 at 20:20
  • It depends on how complex the real data is. If it's only static information, you can do it where you currently create `titleList`. For a data model where the user could add/delete/modify items, you would probably want a "manager" class to handle access through a shared instance. – Phillip Mills Oct 04 '17 at 12:55
2

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

Jacob Boyd
  • 672
  • 3
  • 19