✔ Checkmark selected row in UITableViewCell
Do not use [tableview reloadData];
// its a hammer.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
To set a checkmark:
UITableViewCell *cell = ...;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
To select/deselect a cell:
[cell setSelected:TRUE animated:TRUE]; // select
[cell setSelected:FALSE animated:TRUE]; // deselect
To deselect the previous cell use a NSIndexPath *lastSelected ivar to track the last selected cell:
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
if (self.lastSelected==indexPath) return; // nothing to do
// deselect old
UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected];
old.accessoryType = UITableViewCellAccessoryNone;
[old setSelected:FALSE animated:TRUE];
// select new
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[cell setSelected:TRUE animated:TRUE];
// keep track of the last selected cell
self.lastSelected = indexPath;
}
I found that reloading the data interrupts the deselect animation in an ugly way.
This Swift implementation cleanly adds/removes checkmarks and deselects the row:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if self.lastSelection != nil {
self.myTableView.cellForRowAtIndexPath(self.lastSelection)?.accessoryType = .None
}
self.myTableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
self.lastSelection = indexPath
self.myTableView.deselectRowAtIndexPath(indexPath, animated: true)
}
where lastSelection
is declared as var lastSelection: NSIndexPath!
No extra activity in cellForRowAtIndexPath
needed. Shouldn't be hard to replicate in Obj-C.
In your UITableViewDatasource method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil )
{
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if ([indexPath compare:self.lastIndexPath] == NSOrderedSame)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
// UITableView Delegate Method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.lastIndexPath = indexPath;
[tableView reloadData];
}
And lastIndexPath is a property(strong) NSIndexPath* lastIndexPath;