I am making a CheckList application with a UITableView. I was wondering how to add a swipe to delete a UITableViewCell.
This is my ViewCont
As of Xcode 6.1.1, there are some tiny changes to Dash's answer.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if (editingStyle == UITableViewCellEditingStyle.Delete) {
            // handle delete (by removing the data from your array and updating the tableview)
        }
    }
Another way that allows you to change the text of "Delete" and add more buttons when sliding a cell is to use editActionsForRowAtIndexPath.
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}
func tableView(tableView: (UITableView!), commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: (NSIndexPath!)) {
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
    var deleteAction = UITableViewRowAction(style: .Default, title: "Delete") {action in
       //handle delete
    }
    var editAction = UITableViewRowAction(style: .Normal, title: "Edit") {action in
        //handle edit
    }
    return [deleteAction, editAction]
}
canEditRowAtIndexPath and commitEditingStyle are still required, but you can leave commitEditingStyle empty since deletion is handled in editActionsForRowAtIndexPath.
Swift 5
Since UITableViewRowAction was deprecated in iOS 13.0 so you can use UISwipeActionsConfiguration
   func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let deleteAction = UIContextualAction(style: .destructive, title: "Delete") {  (contextualAction, view, boolValue) in
            self.deleteData(at: indexPath)
        }
        let editAction = UIContextualAction(style: .normal, title: "Edit") {  (contextualAction, view, boolValue) in
            self.editData(at: indexPath)
        }
        editAction.backgroundColor = .purple
        let swipeActions = UISwipeActionsConfiguration(actions: [deleteAction,editAction])
        return swipeActions
    }
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    func deleteData(at indexPath: IndexPath) {
        print(indexPath.row)
    }
    func editData(at indexPath: IndexPath) {
        print(indexPath.row)
    }
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
{
    let delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "DELETE"){(UITableViewRowAction,NSIndexPath) -> Void in
        print("What u want while Pressed delete")
    }
    let edit = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "EDIT"){(UITableViewRowAction,NSIndexPath) -> Void in
        print("What u want while Pressed Edit")
    }
    edit.backgroundColor = UIColor.blackColor()
    return [delete,edit]
}
here See my result Swift with fully customizable button supported
Advance bonus for use this only one method implementation and you get a perfect button!!!
 func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let action = UIContextualAction(
            style: .destructive,
            title: "",
            handler: { (action, view, completion) in
                let alert = UIAlertController(title: "", message: "Are you sure you want to delete this incident?", preferredStyle: .actionSheet)
                alert.addAction(UIAlertAction(title: "Delete", style: .destructive , handler:{ (UIAlertAction)in
                    let model = self.incedentArry[indexPath.row] as! HFIncedentModel
                    print(model.incent_report_id)
                    self.incedentArry.remove(model)
                    tableView.deleteRows(at: [indexPath], with: .fade)
                    delete_incedentreport_data(param: ["incent_report_id": model.incent_report_id])
                    completion(true)
                }))
                alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:{ (UIAlertAction)in
                    tableView.reloadData()
                }))
                self.present(alert, animated: true, completion: {
                })
        })
        action.image = HFAsset.ic_trash.image
        action.backgroundColor = UIColor.red
        let configuration = UISwipeActionsConfiguration(actions: [action])
        configuration.performsFirstActionWithFullSwipe = true
        return configuration
}
Xcode asks for UIContextualAction, here what worked for me for the updated version:
For Trailing Swipe Actions:->
 func delete(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
        let company = companies[indexPath.row]
        let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, _) in
           // Perform Delete Action
        }
        return action
    }
    
    func edit(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
        let action  = UIContextualAction(style: .normal, title: "Edit") { (action, view, escaping) in
            // Perform Edit Action
        }
        return action
    }
    
    override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let delete = self.delete(forRowAtIndexPath: indexPath)
        let edit = self.edit(forRowAtIndexPath: indexPath)
        let swipe = UISwipeActionsConfiguration(actions: [delete, edit])
        return swipe
    }
For Leading Swipe Actions:->
 func delete(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
        let company = companies[indexPath.row]
        let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, _) in
           // Perform Delete Action
        }
        return action
    }
    
    func edit(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
        let action  = UIContextualAction(style: .normal, title: "Edit") { (action, view, escaping) in
            // Perform Edit Action
        }
        return action
    }
    
    override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let delete = self.delete(forRowAtIndexPath: indexPath)
        let edit = self.edit(forRowAtIndexPath: indexPath)
        let swipe = UISwipeActionsConfiguration(actions: [delete, edit])
        return swipe
    }
Return true for canEditRowAt for tableView Delegate:->
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }