Question

I have a UITableViewController that toggles into its editing mode when the user presses a button in the toolbar. I want the user to select multiple cells and then put a rounded red checkmark on the left side of each selected cell. I've selected Multiple Selection During Editing in the table view in Storyboard and no accessory / editing accessory for my custom cell.

The problem is that I can find each tapped cell in the tableView's indexPathsForSelectedRows, but the red checkmark on the left of each selected cell doesn't appear. However, after leaving editing mode, each selected cell shows a checkmark accessory on the right (which I don't need anymore after finishing editing).

While editing: enter image description here After editing: enter image description here

Here is what I did in code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   if (tableView.editing)
   {
       UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
       if ([selectedCell accessoryType] == UITableViewCellAccessoryNone)
       {
           [selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
       }
       else
       {
           [selectedCell setAccessoryType:UITableViewCellAccessoryNone];
       }
   }
}

and

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...
  if (tableView.editing)
  {
      cell.accessoryType = UITableViewCellAccessoryNone;
      for (NSIndexPath *selectedIndex in [self.tableView indexPathsForSelectedRows])
      {
          if ([selectedIndex isEqual:indexPath])
          {
             cell.accessoryType = UITableViewCellAccessoryCheckmark;
             break;
          }
      }
  }
  ...

Thanks!

Was it helpful?

Solution

If anyone comes across the same issue, here is a snipped of how I've solved it. I have a toolbar button connected to an IBAction that toggles the UITableView's editing mode. When editing is enabled, the user can select rows and hit a delete button which has the number of selected rows set in its label.

@interface TableViewController ()
{
    NSMutableArray      *selectedCellRows;      // Used to remember which cells have been selected during editing mode
}

- (IBAction)toggleEditing:(id)sender;

@end


@implementation TableViewController

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    GeneralReservationCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CELL_IDENTIFIER];

    // Set up the cell...
    [self configureCell:cell forTableView:tableView atIndexPath:indexPath];

    return cell;
}

- (void)configureCell:(GeneralReservationCell *)cell forTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath
{
    // Basic layout
    cell.nameLabel.text = @"Some text";

    cell.selected = NO;
    if (tableView.editing)
    {
        for (NSIndexPath *selectedIndex in selectedCellRows)
        {
            if ([selectedIndex isEqual:indexPath])
            {
                cell.selected = YES;
                break;
            }
        }
    }
}


#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.tableView.editing)
    {
        [selectedCellRows addObject:indexPath];
        [self updateEditingToolbarButton];
    }
    else
    {
        // Do whatever you do normally when the cell gets selected
    }
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.tableView.editing)
    {
        [selectedCellRows removeObject:indexPath];
        [self updateEditingToolbarButton];
    }
}


- (void)updateEditingToolbarButton
{
    int selectedRows = [self.tableView.indexPathsForSelectedRows count];

    if (selectedRows == 0)
    {
        [deleteBarButton setTitle:@"delete"];
        deleteBarButton.enabled = NO;
    }
    else
    {
        [deleteBarButton setTitle:[NSString stringWithFormat:@"delete (%d)", selectedRows]];
        deleteBarButton.enabled = YES;
    }
}


#pragma mark - IBActions

- (IBAction)toggleEditing:(id)sender
{
    if(self.tableView.editing)
    {
        [self.tableView setEditing:NO animated:YES];
        [selectedCellRows removeAllObjects];
        [self showToolbarInEditingMode:NO];
    }
    else
    {
        [self.tableView setEditing:YES animated:YES];
        [self showToolbarInEditingMode:YES];
    }
}


@end

Additionally, I set the Editing Accessory to none in Interface Builder.

OTHER TIPS

If you want the rounded circle to be filled when the cell is checked, you need to set the cell's selectionStyle to other than none.

cell.selectionStyle = .blue

This can also be set in the interface builder.

Also you if you don't want the checkmark when not editing the tableView, you need to set the cell's accessoryType to .none in your else block.

if tableView.isEditing {
  ...
} else {
 cell.accessoryType = .none
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top