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 (ie tableView:didSelectRowAtIndexPath is not called). If I tap a second time, then it works correctly (ie 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).


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

    Thanks to all who provided answers or comments to my question. Your comments helped me track down the problem.

    It turns out that we were implementing tableView:shouldHighlightRowAtIndexPath and we were returning NO for the first call after a delete and then returning YES from then on. This is the reason the first tap was ignored. Our full offending code was this:

    -(BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
        if (self.currentPath) {
            [self resetSelectedCell];
            self.currentPath = nil;
            return NO;
        }
        return YES;
    }
    

    This code was provided to prevent more than one delete button from being displayed at once, but we were not resetting self.currentPath correctly after a delete. We are now setting self.currentPath to nil after a successful delete and the code works correctly.

    链接地址: http://www.djcxy.com/p/76068.html

    上一篇: 在Windows 8.1平板电脑上的Web应用程序中捕获图像

    下一篇: 在deleteRowsAtIndexPaths后忽略UITableView