Use didSelectRowAtIndexPath or prepareForSegue method for UITableView?

IosObjective CIphoneUitableviewStoryboard

Ios Problem Overview


I'm using storyboards and I have a UITableView. I have a segue setup that pushes from my table to the detail VC. But which method should I use to handle this? I'll have to pass a couple objects to the detail view. But do I use didSelectRowAtIndex or -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender?

Ios Solutions


Solution 1 - Ios

If you use prepareForSegue:sender:then you won't have as much to change if you later decide to trigger the segue from some control outside the table view.

The prepareForSegue:sender: message is sent to the current view controller, so I'd suggest something like this:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Assume self.view is the table view
    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
    DetailObject *detail = [self detailForIndexPath:path];
    [segue.destinationViewController setDetail:detail];
}

In Swift:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let path = self.tableView.indexPathForSelectedRow()!
    segue.destinationViewController.detail = self.detailForIndexPath(path)
}

Solution 2 - Ios

I did this and it worked

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
    NSLog(@"Row Selected = %i",indexPath.row);
    
    [self performSegueWithIdentifier:@"testID" sender:self.view];    
}

Solution 3 - Ios

When sender is UITableViewCell, you may ask UITableView to query indexPath of the cell.

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let cell = sender as? UITableViewCell {
let indexPath = self.tableView.indexPathForCell(cell)!
assert(segue.destinationViewController.isKindOfClass(DetailViewController))
let detailViewController = segue.destinationViewController as! DetailViewController
detailViewController.item = self.items[indexPath.row] // like this
}
}

Solution 4 - Ios

if your tableView property is in another class and you only have one section, then you could use the tag property to store the cell's row like:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

     cell.tag = indexPath.row;

     return cell;
}

And then you can access it as the sender is the same cell with the row value in its tag:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    MyDestinationViewController *destinationViewController = segue.destinationViewController;
    destinationViewController.myProperty = [tableViewElementsArray objectAtIndex:[sender tag]]; // sender will be your cell 
}

Solution 5 - Ios

self.tableView.indexPathForSelectedRow returns selected cell, but not segue sender cell, e.g. sender cell is not selected (accessory action), or in multiple selection case. The best way is getting indexPath for segue sender:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    __auto_type itemViewController = (id<ItemViewController>)segue.destinationViewController;
    itemViewController.senderIndexPath = [self.tableView indexPathForCell:sender];
}

In Swift:

protocol ItemViewController {
    var senderIndexPath : IndexPath? { get set }
    var selectedIndexPaths : [IndexPath]? { get set }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if  let cell = sender as? UITableViewCell,
        var itemViewController = segue.destination as? ItemViewController {
        itemViewController.senderIndexPath = tableView.indexPath(for: cell)
        itemViewController.selectedIndexPaths = tableView.indexPathsForSelectedRows
    }
}

Solution 6 - Ios

If you use prepareForSegue: you can check who is the sender and execute different code

For example in swift

override func prepareForSegue(segue: UiStoryboardSegue, sender: AnyObject?)
{
   var senderIsTableviewCell:Bool! = sender?.isKindOfClass(UITableViewCell)

   if senderIsTableviewCell
   {
       //do something
   }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJonView Question on Stackoverflow
Solution 1 - Iosrob mayoffView Answer on Stackoverflow
Solution 2 - IosAshishView Answer on Stackoverflow
Solution 3 - IosKaz YoshikawaView Answer on Stackoverflow
Solution 4 - IosLaszloView Answer on Stackoverflow
Solution 5 - IosStanislav P.View Answer on Stackoverflow
Solution 6 - IosEugeneView Answer on Stackoverflow