I write custom jabber client in iphone.
I use xmppframework as engine.
And I have UITableViewController with NSMutableArray for repesent contact list.
<The easy way is something like this:
NSIndexPath *ipath = [self.tableView indexPathForSelectedRow];
[self.tableView reloadData];
[self.tableView selectRowAtIndexPath:ipath animated:NO scrollPosition:UITableViewScrollPositionNone];
I solved it better by declaring an array to store, let's say, the ID or String Text of the cell you have selected, and adding it on the didSelectItemAtIndexPath function. This way, even if the number of rows changes, the selected ones won't. For example:
var selectedItems: [String] = [] // This array type really depends on your preference and what property you're using to store
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) else { return }
selectedItems.append(cell.textField.text)
}
And on your initial cellForItemAtIndexPath
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath)
if let text = cell.textField.text {
if selectedItems.contains(text) {
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
}
}
return cell
}
Adding a bit to Marco's answer:
First, if you're using multiple selection, you can add this method to your ViewController
and call it whenever you need to call [tableView reloadData]
:
- (void)reloadTableView
{
NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
[self.tableView reloadData];
for (NSIndexPath *path in indexPaths) {
[self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
Second, if you're in a UITableViewController
and you want to preserve selection after tableView appears there's a feature in UITableViewController: clearsSelectionOnViewWillAppear
you can turn on or off.
See here: http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewController_Class/Reference/Reference.html
It sounds like you are not using a 'model' for the data - rather simply updating the 'view' (user interface), and thus is probably a bad design.
reloadData should cause the view to be updated with data from the model, which should contain the most current data to be displayed.
search for resources on the 'model view controller pattern'
On iOS 9.3 and Swift 2.x, I simply had to call the function on the main thread :)
self.tableView?.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
This works for me:
NSIndexPath *indexPath = [table indexPathForSelectedRow];
[table reloadData];
double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.table selectRowAtIndexPath:indexPath animated:YES
scrollPosition:UITableViewScrollPositionNone];
});
The trick is to make selectRowAtIndexpath run later a bit. The code above is an Xcode template you can select when you start writing dispatch_after
.