Am I correct in thinking that to change the checkmark for "on" to "off", I must change the CellAccessoryType between none and checkmark on the didSelectRowAtIndexPath?
Because I have done this but I have noticed the behaviour is not perfectly identical to like the checkmark cells on the auto lock settings on the iphone.
Or is there some other way checkmarks are meant to be handled?
Keep a property in your view controller called
selectedRow, which represents the index of a row that represents the checked item in a table section.In your view controller's
-tableView:cellForRowAtIndexPath:delegate method, set theaccessoryTypeof thecelltoUITableViewCellAccessoryCheckmarkif the cell'sindexPath.rowequals theselectedRowvalue. Otherwise, set it toUITableViewCellAccessoryNone.In your view controller's
-tableView:didSelectRowAtIndexPath:delegate method, set theselectedRowvalue to theindexPath.rowthat is selected, e.g.:self.selectedRow = indexPath.row
Another solution:
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *oldIndex = [self.tableView indexPathForSelectedRow];
[self.tableView cellForRowAtIndexPath:oldIndex].accessoryType = UITableViewCellAccessoryNone;
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
return indexPath;
}
And yeah: you don't have to check if oldIndex is nil :)
Swift 3 and later:
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if let oldIndex = tableView.indexPathForSelectedRow {
tableView.cellForRow(at: oldIndex)?.accessoryType = .none
}
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
return indexPath
}
Zyphrax suggested a great solution that worked great for me! And if you need to clear the previous selected row, just use:
[self.tableView reloadData];
in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
It should be
didHighlightRowAtIndexPath
instead of
tableView:didSelectRowAtIndexPath
Alex answer worked for me only after adding reload table , in .h
{
int selectedCell;
}
@property(nonatomic,readwrite)int selectedCell;
in .m *cellForRowAtIndexPath*
if(indexPath.row == selectedCell)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.selected = YES;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selected = NO;
}
and in anywhere didHighlightRowAtIndexPath or didSelectRowAtIndexPath
self.selectedCell = indexPath.row;
[self.tableView reloadData];
swift:
var selectedCell:UITableViewCell?{
willSet{
selectedCell?.accessoryType = .None
newValue?.accessoryType = .Checkmark
}
}
then:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedCell = self.tableView.cellForRowAtIndexPath(indexPath)
self.mapView.selectAnnotation(self.mapView.annotations[indexPath.row], animated: true)
}
If you want to use your custom image as accessoryType use below code
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIImageView *imgCheckMark = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"select_icon.png"]];
[imgCheckMark setFrame:CGRectMake(self.view.frame.size.width - 30, 25, 14, 18)];
imgCheckMark.tag = 1000+indexPath.row;
NSIndexPath *oldIndex = [self.tblSelectService indexPathForSelectedRow];
[self.tblSelectService cellForRowAtIndexPath:oldIndex].accessoryView = UITableViewCellAccessoryNone;
[self.tblSelectService cellForRowAtIndexPath:indexPath].accessoryView = imgCheckMark;
return indexPath;
}
For swift
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
来源:https://stackoverflow.com/questions/2797165/uitableviewcell-checkmark-change-on-select