How to find indexPath for tapped accessory button in tableView

Guferos picture Guferos · Dec 3, 2012 · Viewed 12.8k times · Source

I've simple UITableView with one section and few rows. When user clicks cell accessory button (which is connected with detailsSegue. I want to know what cell row was it. So than I can select right object from my array and assign it to the variable from the next view.

I have used delegate method tableview:accessoryButtonTappedForRowWithIndexPath: and assigned indexPath value to my private property myRow. Than in prepareForSegue:sender: method I used my self.myRow.row value to select right object from array.

My problem is that these two methods seems to execute in wrong order. From the NSLog I can see that prepareForSegue:sender: method is executed first and my delegate method is changing value of self.myRow after it.

So prepareForSegue:sender: method is always passing wrong object to the next view (the one that was tapped previously).

Sorry for my english guys. Thanks for help in advance.

-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
    self.myRow = indexPath;
    NSLog(@"tapped button at row: %i",self.myRow.row); 
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([segue.identifier isEqualToString:@"addSegue"]) {
        AddViewController *avc = segue.destinationViewController;
        avc.delegate = self;
    }
    else if ([segue.identifier isEqualToString:@"detailsSegue"]) {
        NSLog(@"Segue row: %i",self.myRow.row);
        Annotation *annotation = [self.viewsList objectAtIndex:self.myRow.row];
        NSLog(@"Segue annotation object: %@",annotation.title);
        DetailsViewController *dvc = segue.destinationViewController;
        dvc.wikiKey = annotation.title;
    }
}

Answer

rob mayoff picture rob mayoff · Dec 3, 2012

As you have discovered, the system sends you the prepareForSegue:sender: message before it sends you the tableview:accessoryButtonTappedForRowWithIndexPath: message.

But, when it sends you the prepareForSegue:sender: message, the sender argument is the UITableViewCell containing the accessory view. You can use that to determine which row's accessory button was tapped:

else if ([segue.identifier isEqualToString:@"detailsSegue"]) {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    Annotation *annotation = [self.viewsList objectAtIndex:indexPath.row];
    DetailsViewController *dvc = segue.destinationViewController;
    dvc.wikiKey = annotation.title;
}