UITableViewCell checkmark change on select

Objective CIphoneTablecellCheckmark

Objective C Problem Overview


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?

Objective C Solutions


Solution 1 - Objective C

  1. 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.

  2. In your view controller's -tableView:cellForRowAtIndexPath: delegate method, set the accessoryType of the cell to UITableViewCellAccessoryCheckmark if the cell's indexPath.row equals the selectedRow value. Otherwise, set it to UITableViewCellAccessoryNone.

  3. In your view controller's -tableView:didSelectRowAtIndexPath: delegate method, set the selectedRow value to the indexPath.row that is selected, e.g.: self.selectedRow = indexPath.row

Solution 2 - Objective C

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
}

Solution 3 - Objective C

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)
}

Solution 4 - Objective C

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

Solution 5 - Objective C

It should be

> didHighlightRowAtIndexPath

instead of

> tableView:didSelectRowAtIndexPath

Solution 6 - Objective C

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]; 

Solution 7 - Objective C

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
  }

Solution 8 - Objective C

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;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJonathan.View Question on Stackoverflow
Solution 1 - Objective CAlex ReynoldsView Answer on Stackoverflow
Solution 2 - Objective CYvoView Answer on Stackoverflow
Solution 3 - Objective CBenView Answer on Stackoverflow
Solution 4 - Objective CneowinstonView Answer on Stackoverflow
Solution 5 - Objective CAbid MalikView Answer on Stackoverflow
Solution 6 - Objective CiMeMyselfView Answer on Stackoverflow
Solution 7 - Objective CBatyrCanView Answer on Stackoverflow
Solution 8 - Objective CHardik ThakkarView Answer on Stackoverflow