Search code examples
swifttableviewhierarchical-datadetailviewpass-data

What is the best way to pass data in a hierarchical structure? Swift


So I am working on an app that has several tableviews that take you to a detailview and that detailview can either take you to a mapview or webview, here is an example of what I mean: enter image description here

Instead of making several detail groups (detail,web,map), I just make all the tableviews, take you to the same detailView and put the information there because there are going to be a LOT of rows with information in it so that wouldn't be possible. Now it is not so much of an issue right now, but I think I am not doing things as I should. Basically I pass the information this way: In the "prepareforsegue" funcion, from the tableview to the detailview I use "if indexPath.row == 0", then just pass the information according to the row that was selected, I have an integer variable that is set to the number of the row that was clicked on the tableview and that too, is passed to the detailview so in the detailview I know what website to pass to the webview or location to the mapview, obviously as more spots are added to my tableview, I have to add more "ifs" and I am just not sure if this is the right approach or is there is a simpler way to do this.


Solution

  • You should have a class that encapsulates all the information that relates to a single table row / detail view. Let's call it model.

    In the table view controller you will have an array of models, e.g.

    var models = [model]()
    

    The you would override cellForRowAtIndexPath to return a cell based on the particular model, e.g.

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("someCellId", forIndexPath: indexPath) as! UITableViewCell
    
        let model = models[indexPath.row]
    
        // Set the title of the cell to be the title of the logItem
        cell.textLabel?.text = model.name
        cell.detailTextLabel?.text = model.details
        return cell
    }
    

    In storyboard make a segue to the detail view, then pass an entire model to the detail view

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
        if (segue.identifier == "segueToDetail") {
            var svc = segue.destinationViewController as! DetailViewController
            svc.model = models[tableView.indexPathForSelectedRow()!.row]
        }
    }
    

    This way you are only passing one object and don't have to have set up all the detail view labels etc. Also then the detail view can pass the same object onto the map view or some other view.