Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First tap on UITableView ignored after deleteRowsAtIndexPaths

My UITableView has a collection of cells. Swiping a cell causes a Remove button to appear. Tapping this Remove button causes the following code to be executed:

NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[self.itemList removeObjectAtIndex:indexPath.row];

This correctly causes the cell to be removed from the list. However, when I tap on one of the remaining cells in the UITableVIew to select it, this tap is ignored (i.e. tableView:didSelectRowAtIndexPath is not called). If I tap a second time, then it works correctly (i.e tableView:didSelectRowAtIndexPath is called).

It does not matter which cell I tap after the delete and it doesn't matter how long I wait after the delete, the first tap after the delete is always ignored and the second tap after the delete is successful.

Based on various stackOverflow answers, I have tried:

  • setting self.tableView.editing = NO; after the delete
  • calling [self.tableView reloadData]; after the delete
  • calling [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade]; after the delete
  • calling [self.tableView beginUpdates]; before the delete and [self.tableView endUpdates]; after the delete
  • doing all of the above at the same time

None of the above have helped; the first tap after the delete is still always ignored.

UPDATE: I also added the [self.itemList removeObjectAtIndex:indexPath.row]; code to the code snippet above. My datasource delegate methods look like this:

-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.itemList.count;
}

The code snippet above is being called in the doDelete method in response to a button tap ([self.deleteButton addTarget:self action:@selector(doDelete) forControlEvents:UIControlEventTouchUpInside];)

UPDATE #2: Based on Lyssa's comments, I have tried the following: I removed all references to our custom Delete button and our swipe gesture and then added this code to our UITableView delegate:

-(BOOL) tableView:(UITableView*)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

-(void) tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.itemList removeObjectAtIndex:indexPath.row];
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    }
}

That does work - I can now delete rows and the next tap does work correctly. However, this removes our custom look and feel for our table cell, which was the purpose of our custom code in the first place. Perhaps I should be looking at using the above methods and customizing the Delete button instead (I have done some looking and not found a good answer yet).

like image 619
Tom Avatar asked Dec 10 '13 14:12

Tom


1 Answers

The problem is that when you use swipe-to-delete only the row you swipe enters edit mode.

And the first tap is ending editing mode for that row:

- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath {
}

you can solve it by setting editing mode

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.itemList removeObjectAtIndex:indexPath.row];
        [self.tableView setEditing:NO animated:YES];
    }
    [self.tableView reloadData];
}
like image 97
mfr Avatar answered Oct 19 '22 18:10

mfr