How to enable swipe to delete cell in a TableView?

IosUitableviewUiswipegesturerecognizer

Ios Problem Overview


I have a UIViewController that implements TableViews delegate and datasource protocols. Now I want to add "swipe to delete" gesture to cells.

How should I go about it.

I have given a blank implementation of commitEditingStyle method and also set the Editing property to YES.

Still the swipe feature is not coming .

Now Do I need to separately add UISwipeGesture to each cell ?

Or am I missing something ?

Ios Solutions


Solution 1 - Ios

As [Dan][1] has commented above, you need to implement the following table view delegate methods:

  1. tableView:canEditRowAtIndexPath:
  2. tableView:commitEditingStyle:forRowAtIndexPath:

Note: I have tried this in iOS 6 and iOS 7.

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return YES - we will be able to delete all rows
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Perform the real delete action here. Note: you may need to check editing style
    //   if you do not perform delete only.
    NSLog(@"Deleted row.");
}

[1]: https://stackoverflow.com/users/39155/dan "Dan"

Solution 2 - Ios

You don't have to set editing:YES if you need to show Delete button on cell swipe. You have to implement tableView:canEditRowAtIndexPath: and return YES from there for rows you need to edit/delete. This is not necessary when your tableView's dataSource is a subclass of UITableViewContoller - this method, if not overridden, returns YES by default. In all other cases you have to implement it.

EDIT: Together we have found the problem - tableView:editingStyleForRowAtIndexPath: returned UITableViewCellEditingStyleNone if table wasn't in editing mode.

Solution 3 - Ios

// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}



// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}

Solution 4 - Ios

Please try this code in swift,

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
   // let the controller to know that able to edit tableView's row 
   return true
}

override func tableView(tableView: UITableView, commitEditingStyle editingStyle UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)  {
   // if you want to apply with iOS 8 or earlier version you must add this function too. (just left in blank code)
}

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?  {
   // add the action button you want to show when swiping on tableView's cell , in this case add the delete button.
   let deleteAction = UITableViewRowAction(style: .Default, title: "Delete", handler: { (action , indexPath) -> Void in

   // Your delete code here.....
   .........
   .........
   })

   // You can set its properties like normal button
   deleteAction.backgroundColor = UIColor.redColor()

   return [deleteAction]
}

Solution 5 - Ios

Try adding the following to your class:

// Override to support conditional editing of the table view.
- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return(YES);
}

Solution 6 - Ios

Conclusion of Kyr Dunenkoff chat is

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {

}

should not be defined if you need delete button to appear on swipe.

Solution 7 - Ios

If you are using an NSFetchedResultsControllerDelegate to populate the table view, this worked for me:

  • Make sure tableView:canEditRowAtIndexPath returns true always

  • In your tableView:commitEditingStyle:forRowAtIndexPath implementation, do not delete the row directly from the table view. Instead, delete it using your managed object context, e.g.:

     if editingStyle == UITableViewCellEditingStyle.Delete {
         let word = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Word
         self.managedObjectContext.deleteObject(word)
         self.saveManagedObjectContext()
     }
    
     func saveManagedObjectContext() {
         do {
             try self.managedObjectContext.save()
         } catch {
             let saveError = error as NSError
             print("\(saveError), \(saveError.userInfo)")
         }
     }
    

Solution 8 - Ios

This was a problem for me too...I could only get swiping to delete to work once every 10 or so attempts. It turns out the gesture on the TV was being blocked by another gesture in the parent view controller. The TV was nested in a MMDrawerController (swipe able drawer layout).

Just configuring the gesture recognizer in the drawer controller to not respond to close gestures in the flanking drawers allowed swipe to delete to work in my TV.

You could also try doing something like this with the gesture delegate:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

Solution 9 - Ios

This is the swift version

// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return NO if you do not want the specified item to be editable.
    return true
}

// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete {
        // Delete the row from the data source
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    } else if editingStyle == .Insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }    
}

Solution 10 - Ios

In my experience, seems like you must have editing on UITableView set to NO for swiping to work.

self.tableView.editing = NO;

Solution 11 - Ios

After iOS 8.0, you can custom you action in

- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath

Solution 12 - Ios

NSMutableArray *post= [NSMutableArray alloc]initWithObject:@"1",@"2",@"3",nil]; 


- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView 
		   editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
	
	NSUInteger row = [indexPath row];
	NSUInteger count = [posts count];
	
	if (row < count) {
		return UITableViewCellEditingStyleDelete;
	} else {
		return UITableViewCellEditingStyleNone;
	}
}

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

	NSUInteger row = [indexPath row];
	NSUInteger count = [posts count];

	if (row < count) {
		
		[posts removeObjectAtIndex:row];
	}
}

Solution 13 - Ios

You can see all necessary methods by creating a UITableViewController class (temporary) in XCode 5 and then copy which method you would like to use. Those methods you need will be commented out with pre-filled in lines you desire.

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
QuestionAmogh TalpallikarView Question on Stackoverflow
Solution 1 - IosDj SView Answer on Stackoverflow
Solution 2 - IosKyr DunenkoffView Answer on Stackoverflow
Solution 3 - IosCan AksoyView Answer on Stackoverflow
Solution 4 - IosMasa S-AiYaView Answer on Stackoverflow
Solution 5 - IosDavid M. SyzdekView Answer on Stackoverflow
Solution 6 - IosThiruView Answer on Stackoverflow
Solution 7 - IosGabeVView Answer on Stackoverflow
Solution 8 - IosKevinView Answer on Stackoverflow
Solution 9 - IosJZAUView Answer on Stackoverflow
Solution 10 - IoskgaidisView Answer on Stackoverflow
Solution 11 - Iosuser501836View Answer on Stackoverflow
Solution 12 - IosVimal RavalView Answer on Stackoverflow
Solution 13 - IosEmin Bugra SaralView Answer on Stackoverflow