UITableView - IndexPath always returns 0 first & takes 2 clicks to pass correct data to view controller

I have a UITableView that segues to a ViewController. My tableview contains a list of location names and when you select a location, it passes more detailed data to the view controller about the selected location. My issue is that my index path always returns 0 on the first click / load no matter which row I click. I have to click each row twice for it pass the right data.

Example: I click row2 > returns row1's (0) data. I then click row2 again > correctly returns row2's data > I then click row3 > returns row2's data > I have to click row3 again to get row3's data. indexPathSelected in the below code is always 0 on load.

NSInteger indexPathSelected;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    indexPathSelected = indexPath.row;
}

#pragma mark - Navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showLocationDetails"])

    {
        LocationDetailsViewController *vc = [segue destinationViewController];
        vc.location = _locationsArray [indexPathSelected];

    }
}

Answers


The problem is that prepareForSegue is called before didSelectRowAtIndexPath. When using segues, it's not usually necessary to implement didSelectRowAtIndexPath at all. The sender argument in prepareForSegue:sender: is the cell you selected,, so you can get the index path from it:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showLocationDetails"])

    {
        LocationDetailsViewController *vc = [segue destinationViewController];
        indexPathSelected = [self.tableView indexPathForCell:sender].row;
        vc.location = _locationsArray[indexPathSelected];

    }
}

prepareForSegue:sender: is probably being called before tableView:didSelectRowAtIndexPath:, so the first load is initializing indexPathSelected with 0 as a default, then passing the previous value each time.

I'd get rid of tableView:didSelectRowAtIndexPath: and change prepareForSegue:sender: as follows:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showLocationDetails"])

    {
        LocationDetailsViewController *vc = [segue destinationViewController];
        NSIndexPath selectedIndexPath = [[self tableView] indexPathForSelectedRow];
        vc.location = _locationsArray[[selectedIndexPath row]];
    }
}

It should accomplish the same thing you wanted.


Need Your Help

iPhone Developer Program registration for UK trading partnership

iphone iphone-developer-program app-store

I have been looking into this for a long time and have found no definitive answer. I can't be the only person to have faced this problem and am wondering how you guys proceeded in similar cases.

Jasper Report export crashes

jasper-reports jasperserver crosstab

I have a crosstab report that outputs 75 pages.