I have a UIViewController
that implements TableViews delegate and datasource protocols.
Now I want to add \"swipe to delete\" gesture to cells.
After iOS 8.0, you can custom you action in
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
As Dan has commented above, you need to implement the following table view delegate methods:
tableView:canEditRowAtIndexPath:
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.");
}
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.
If you are using an NSFetchedResultsControllerDelegate
to populate the table view, this worked for me:
tableView:canEditRowAtIndexPath
returns true alwaysIn 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)")
}
}
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]
}
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);
}