2

I've got a UITableView that when selecting a UITableViewCell I call a web service to fetch new data and then reload the UITableView with the new data.

Now, the selected row will always be part of the new data that comes back. However the number of rows in a section won't be constant.

I am trying to keep selection on the row that was selected after I reload the table view. I saved the indexPath from didSelectRowAtIndexPath. However when I call:

    [self.tableView selectRowAtIndexPath:self.selectedIndexPath 
                                animated:NO 
                          scrollPosition:UITableViewScrollPositionNone];

Nothing happens and my row I selected is no longer selected after the reload. Is there anyway to keep selection after a reload of UITableView?

Alex Cio
  • 6,014
  • 5
  • 44
  • 74
Robert J. Clegg
  • 7,231
  • 9
  • 47
  • 99
  • Can you add some kind of selection flag to the data? – DogCoffee Apr 24 '14 at 07:34
  • The data is in an array - I get a new copy of the data each time selection happens as the data changes. What is constant and always guaranteed is getting back the selected item from the new data. – Robert J. Clegg Apr 24 '14 at 07:41
  • http://stackoverflow.com/questions/1827176/save-selected-row-in-uitableview-after-reloaddata – Suhit Patil Apr 24 '14 at 07:47
  • Put the selected item in a local iVar, put an equality check in the cellforrowatindex path, so when its reloading the cells, it will compare in incoming data with you saved iVar. If its a match the you call the selecteRowAtIndexPath method. – DogCoffee Apr 24 '14 at 12:03

2 Answers2

3

Try

dispatch_async(dispatch_get_main_queue(), ^{ 
      [self.tableView selectRowAtIndexPath:self.selectedIndexPath 
                                  animated:NO 
                            scrollPosition:UITableViewScrollPositionNone];
});

Also, make sure, that your self.indexPath property will represent the same cell after reloading the UITableView.

Alex Cio
  • 6,014
  • 5
  • 44
  • 74
  • This didn't help. I think maybe the problem is that the cell moves to a different row. Its still in the same section but moves from row 4 (for example) to row 1 as its the only item left in that section? – Robert J. Clegg Apr 24 '14 at 07:59
  • So you shouldn't rely to indexPath. You need to save selected element of your data and find it index in new data after reload. With this index you will be able to create NSIndexPath object and select valid cell – Daniil Rumyantsev Apr 24 '14 at 08:04
  • How would I save the selected element? The data model gets refreshed when I reload the tableview. I don't store the data it gets free'd from memory when I no longer need it. I can get selection working if I save the index path as 0. But as you pointed out, this may lead to issues if there is more than one row.. – Robert J. Clegg Apr 24 '14 at 08:08
  • Then I believe you have two options. Store your data and selected element during all table view life cycle, or keep info about selected element directly in data – Daniil Rumyantsev Apr 24 '14 at 08:37
  • 1
    Save by indexPath, i think it can not work because data you get from server is always changes. When you click a row, you save key-id (i means key that you can distinguish between cells). After that for-loop to find that key, at that time, you will get actual indexPath. – nmh Apr 24 '14 at 15:17
1

Before reloadData, preserve the selected index path(s). After reload, use selectRowAtIndexPath:, to set selected rows back again e.g.

NSArray<NSIndexPath *> *indexPathsForSelectedRows = self.itemsTableView.indexPathsForSelectedRows; // multiple selection

NSIndexPath *indexPathForSelectedRow = self.itemsTableView.indexPathForSelectedRow;   // single selection

[self.tableView reloadData];

[self.tableView selectRowAtIndexPath:indexPathForSelectedRow animated:NO scrollPosition:UITableViewScrollPositionNone]; // single selection

for (int i = 0; i < indexPathsForSelectedRows.count; i++) {
    [self.tableView selectRowAtIndexPath:indexPathsForSelectedRows[i] animated:NO scrollPosition:UITableViewScrollPositionNone]; // multiple selection
}
malhal
  • 26,330
  • 7
  • 115
  • 133
Beyond Chao
  • 115
  • 1
  • 5