do it better
do it better

Reputation: 4807

How to change content of the destination view controller according to tapped UITableCell?

I have two view controllers as UITableViewController and DestinationViewController. The content of DestinationViewController should change according to tapped UITableViewCell. I tried this tutorial but this one didn't make sense. How can I determine which cell is tapped and how can I perform segue when the cell tapped?

EDIT:

UITableViewController:

let days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

var myIndex: Int?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    table1View.deselectRowAtIndexPath(indexPath, animated: true)
    myIndex = indexPath.row
    self.performSegueWithIdentifier("showClassesForSchedule", sender: nil)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let identifier = segue.identifier {
        switch identifier {
        case "showClassesForSchedule":
            let destinationViewController = segue.destinationViewController as? ScheduleAsClassTableViewController// set here нour destionation VC
            if destinationViewController != nil {
                destinationViewController?.tableArray.append(days[myIndex!])
                destinationViewController?.tableArray = days
                print(days[myIndex!])
            }
        default: break
        }
    }
}


func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("scheduleDaysTextCellIdentifier", forIndexPath: indexPath) as UITableViewCell

    let row = indexPath.row
    cell.textLabel?.text = days[row]

    return cell
}

DestinationViewController:

    var tableArray = [String]()
    @IBOutlet var table1View: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        print(tableArray)
    }
    @IBOutlet weak var comingLabelAsNormalView: UILabel!

    @IBOutlet weak var comingName: UILabel!

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return tableArray.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = table1View.dequeueReusableCellWithIdentifier("scheduleDayClassIdentifier", forIndexPath: indexPath) as UITableViewCell

        let row = indexPath.row
        cell.textLabel?.text = tableArray[row]

        return cell
    }

Upvotes: 0

Views: 686

Answers (2)

Gordonium
Gordonium

Reputation: 3487

There are a few ways of doing this. I'd recommend using segues. This method doesn't require didSelectRowAtIndexPath.

Firstly, create a segue by right clicking and dragging from your prototype cell to the next view controller and choosing Show:

enter image description here

Then give the segue an identifier:

enter image description here

Next you need a reference to the index path of the particular cell that was tapped. You can do this in prepareForSegue. Try something like this:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "detail" {
        if let cell = sender as? UITableViewCell{
            if let indexPath = self.tableView.indexPathForCell(cell) {
                // get a reference to the next view controller so you can pass data in
                var nvc = segue.destinationViewController as! NewViewController

                // set properties on the next view controller using the acquired cell's index
                nvc.name = names[indexPath.row]
            }
        }
    }
}

The above code checks for the segue identifier. sender in this case is the UITableViewCell that the user tapped. The next two lines try to get a reference to this cell and its associated indexPath. You can then use indexPath.row or indexPath.section as requied before you segue in order to access relevant data. Then a reference is obtained to the next view controller (for which you should have created an associated class and hooked it up in interface builder) and whatever properties you would like to set can then be set on this reference.

Upvotes: 1

mkz
mkz

Reputation: 2302

You can perform a segue in tableView didSelectRowAtIndexPath. Then in prepareForSegue method set your destinationVC and pass needed data.

Code:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let identifier = segue.identifier {
        switch identifier {
        case "yourSegueIdentifier":
            let destinationViewController = segue.destinationViewController as? UIViewController // set here нour destionation VC
            if destinationViewController != nil {
                destinationViewController?.passedData = yourData
            }
        default: break
        }
    }
}

Don't forget to create a segue and set the identifier. If you have questions ask in comments.

Here is your tableView didSelectRowAtIndexPath:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
    // save indexPath to any Int variable
    myIndex = indexPath.row
    self.performSegueWithIdentifier("yourSegueIndentifier", sender: nil)
}

Upvotes: 1

Related Questions