Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access segue in 'didSelectRowAtIndexPath'?

I know how to pass data using segues from prepareForSegue function, but the thing i have a TableViewCell from which there are two possible segues to two different ViewControllers (let's just say A, B as of now).

It was suggested here that it is best to connect the segues to View controller rather than the tableCell itself, which infact worked perfectly. But i want to pass information to the second View controller when the cell is clicked, So how to access segue that i connected to the Source ViewController.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  if segue.identifier == "showQuestionnaire"{
    if let indexPath = self.tableView.indexPathForSelectedRow() {
      let controller = (segue.destinationViewController as! UINavigationController).topViewController as! QuestionnaireController
      let patientQuestionnaire = patientQuestionnaires[indexPath.row] as! PatientQuestionnaire
      controller.selectedQuestionnaire = patientQuestionnaire
      self.performSegueWithIdentifier("showQuestionnaire", sender: self)
    }
  }
}

Again: This question is not regarding passing information through prepareForSegue

like image 605
Sashi Avatar asked Apr 30 '15 18:04

Sashi


1 Answers

You should be using the didSelectRowAtIndexPath method to determine whether or not a cell was selected, and send the indexPath as the sender of the segue:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.performSegueWithIdentifier("showQuestionnaire", sender: indexPath);
}

Then in your prepareForSegue method, get the indexPath from the sender parameter and use that to pass the correct row/data:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == "showQuestionnaire") {
        let controller = (segue.destinationViewController as! UINavigationController).topViewController as! QuestionnaireController
        let row = (sender as! NSIndexPath).row; //we know that sender is an NSIndexPath here.
        let patientQuestionnaire = patientQuestionnaires[row] as! PatientQuestionnaire 
        controller.selectedQuestionnaire = patientQuestionnaire
    }
}

To explain...

  1. I used the index path as the sender so I can easily pass the index path. You could also check for the currently selected cell using other UITableView methods, but I've always done it this way with success
  2. You can't put performSegueWithIdentifier within the prepare for segue method, because performSegueWithIdentifier leads to prepareForSegue; You are just looping around and around with no aim. (When you want to perform a segue, prepareForSegue is always executed)
  3. prepareForSegue doesn't run by itself when a row is selected. This is where you need didSelectRowAtIndexPath. You need a performSegueWithIdentifier outside of the method as described previously, which should be in didSelectRowAtIndexPath
like image 200
Nate Lee Avatar answered Oct 27 '22 04:10

Nate Lee