Lorenzo B
Lorenzo B

Reputation: 33428

tableView:didEndEditingRowAtIndexPath: delegate method called twice

I would like to know when the user applies swipe actions on cells of a UITableView. As per the doc, the UITableViewDelegate methods should I use are the following:

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;

The willBegin... is called once while the didEnd... is called twice. Is there any reason for this?

My goal is to know when the user has performed a swipe gesture on a cell, followed by a cancel one (he doesn't want to delete anything). This in order to restore the previous selected cell if no action was performed (as per UITableView loses selection).

Any hints?

Upvotes: 4

Views: 1499

Answers (2)

Lorenzo B
Lorenzo B

Reputation: 33428

My solution is described in my blog Restore the selection of a UITableViewCell after cancelling the “Swipe to delete” operation (Dec 22nd, 2014). To summarize, use a boolean value that keeps track of operations.

I opened a radar. I will wait for a reply and I will update with the feedback.

func tableView(tableView: UITableView, willBeginEditingRowAtIndexPath indexPath: NSIndexPath) {

    self.swipeGestureStarted = true
}

func tableView(tableView: UITableView, didEndEditingRowAtIndexPath indexPath: NSIndexPath) {
    if(self.swipeGestureStarted) {
        self.swipeGestureStarted = false

        self.tableView.selectRowAtIndexPath(self.selectedIndexPath, animated: true, scrollPosition: .None)
    }
}

Upvotes: 3

Luke
Luke

Reputation: 11476

I encountered this problem too, and was able to solve it by declaring a BOOL as a member to my view controller:

@interface ViewController ()

@property (nonatomic, assign) BOOL isEditingRow;

@end

@implementation ViewController

...

... and then setting and reading the value of the BOOL in the UITableView's delegate methods:

-(void)tableView: (UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath*)indexPath
{
    self.isEditingRow = YES;
}

-(void)tableView: (UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath*)indexPath
{
    if (self.isEditingRow)
    {
        self.isEditingRow = NO;

        // now do processing that you want to do once - not twice!
    }
}

It's more of a workaround, but very frustrating that this occurs at all.

Upvotes: 2

Related Questions