UITableView disable swipe to delete, but still have delete in Edit mode?

IosCocoa TouchUitableviewUikit

Ios Problem Overview


I want something similar as the Alarm app, where you can't swipe delete the row, but you can still delete the row in Edit mode.

When commented out tableView:commitEditingStyle:forRowAtIndexPath:, I disabled the swipe to delete and still had Delete button in Edit mode, but what happens when I press the Delete button. What gets called?

Ios Solutions


Solution 1 - Ios

Ok, it turns out to be quite easy. This is what I did to solve this:

Objective-C

- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Detemine if it's in editing mode
    if (self.tableView.editing)
    {
        return UITableViewCellEditingStyleDelete;
    }

    return UITableViewCellEditingStyleNone;
}

Swift 2

override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
    if tableView.editing {
         return .Delete
    }

    return .None
}

Swift 3

override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
    if tableView.isEditing {
        return .delete
    }
    
    return .none
}

You still need to implement tableView:commitEditingStyle:forRowAtIndexPath: to commit the deletion.

Solution 2 - Ios

Just to make things clear, swipe-to-delete will not be enabled unless tableView:commitEditingStyle:forRowAtIndexPath: is implemented.

While I was in development, I didn't implement it, and therefore swipe-to-delete wasn't enabled. Of course, in a finished app, it would always be implemented, because otherwise there would be no editing.

Solution 3 - Ios

You need to implement the CanEditRowAt function.

You can return .delete in the EditingStyleForRowAt function so you can still delete in editing mode.

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    if tableView.isEditing {
        return true
    }
    return false
}

func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
    return .delete
}

Solution 4 - Ios

Swift Version:

override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
   
    if(do something){
        
        return UITableViewCellEditingStyle.Delete or UITableViewCellEditingStyle.Insert
      
    }
    return UITableViewCellEditingStyle.None
    
}

Solution 5 - Ios

Basically, you enable or disable editing using the methods

- (void)setEditing:(BOOL)editing animated:(BOOL)animated

If editing is enabled, the red deletion icon appears, and a delete conformation requested to the user. If the user confirms, the delegate method

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

is notified of the delete request. If you implement this method, then swipe to delete is automatically made active. If you do not implement this method, then swipe to delete is not active, however you are not able to actually delete the row. Therefore, to the best of my knowledge, you can not achieve what you asked for, unless using some undocumented, private APIs. Probably this is how the Apple application is implemented.

Solution 6 - Ios

On C#:

I had the same issue where it was needed to enable/disable rows with Delete option on swipe. Multiple rows needed to be swiped left and get deleted, keep them in another colour. I achieved using this logic.

[Export("tableView:canEditRowAtIndexPath:")]
public bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
{

    if (deletedIndexes.Contains(indexPath.Row)){
        return false;
    }
    else{
        return true;
    }

}

Note that deletedIndexes are a list of indexes which are deleted from the table without duplicates. This code check whether a row is deleted, then it disables swipe or vice versa.

The equivalent delegate function is Swift is canEditRowAtIndexPath.

Solution 7 - Ios

I came across this problem either and fixed with codes below. hope it will help you.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
    
    BOOL deleteBySwipe = NO;
    for (UIGestureRecognizer* g in tableView.gestureRecognizers) {
        if (g.state == UIGestureRecognizerStateEnded) {
            deleteBySwipe = YES;
            break;
        }
    }
    
    if (deleteBySwipe) {
        //this gesture may cause delete unintendedly
        return;
    }
    //do delete
}

}

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
QuestionwilliView Question on Stackoverflow
Solution 1 - IoswilliView Answer on Stackoverflow
Solution 2 - IosMarc RochkindView Answer on Stackoverflow
Solution 3 - IosNoodybrankView Answer on Stackoverflow
Solution 4 - IoskareemView Answer on Stackoverflow
Solution 5 - IosMassimo CafaroView Answer on Stackoverflow
Solution 6 - IosAlvin GeorgeView Answer on Stackoverflow
Solution 7 - Iosuser4272677View Answer on Stackoverflow