Full swipe UITableViewCell to delete UITableView iOS 8 Full swipe UITableViewCell to delete UITableView iOS 8 ios ios

Full swipe UITableViewCell to delete UITableView iOS 8


With Swift 4.2 and iOS 12, according to your needs, you can choose one of the 3 following ways in order to create a trailing swipe action that will delete the selected UITableViewCell.


#1. Using UITableViewDataSource's tableView(_:commit:forRowAt:)

When you use tableView(_:commit:forRowAt:) with an editingStyle of value UITableViewCell.EditingStyle.delete, full swipe to delete is automatically supported by the system.

import UIKitclass TableViewController: UITableViewController {    var numbers = [Int](0..<10)    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return numbers.count    }    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)        cell.textLabel?.text = "\(numbers[indexPath.row])"        return cell    }    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {        if (editingStyle == UITableViewCell.EditingStyle.delete) {            self.numbers.remove(at: indexPath.row)            tableView.deleteRows(at: [indexPath], with: .fade)        }    }}

#2. Using UITableViewDelegate's tableView(_:editActionsForRowAt:) and UITableViewRowAction

In order to support full swipe to delete with UITableViewRowAction, you have to initialize it with a style that has a value of UITableViewRowAction.Style.destructive.

import UIKitclass TableViewController: UITableViewController {    var numbers = [Int](0..<10)    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return numbers.count    }    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)        cell.textLabel?.text = "\(numbers[indexPath.row])"        return cell    }    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {        // Intentionally blank in order to be able to use UITableViewRowActions    }    override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {        let deleteHandler: (UITableViewRowAction, IndexPath) -> Void = { _, indexPath in            self.numbers.remove(at: indexPath.row)            tableView.deleteRows(at: [indexPath], with: .fade)        }        let deleteAction = UITableViewRowAction(style: UITableViewRowAction.Style.destructive, title: "Delete", handler: deleteHandler)        // Add more actions here if required        return [deleteAction]    }}

#3. Using UITableViewDelegate's tableView(_:trailingSwipeActionsConfigurationForRowAt:) and UISwipeActionsConfiguration (requires iOS 11)

UISwipeActionsConfiguration has a property called performsFirstActionWithFullSwipe. performsFirstActionWithFullSwipe has the following declaration:

var performsFirstActionWithFullSwipe: Bool { get set }

A Boolean value indicating whether a full swipe automatically performs the first action. [...] When this property is set to true, a full swipe in the row performs the first action listed in the actions property. The default value of this property is true.

The following UITableViewController implementation show how to use UISwipeActionsConfiguration in order to manage full swipe to delete actions.

import UIKitclass TableViewController: UITableViewController {    var numbers = [Int](0..<10)    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return numbers.count    }    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)        cell.textLabel?.text = "\(numbers[indexPath.row])"        return cell    }    override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {        let handler: UIContextualAction.Handler = { (action: UIContextualAction, view: UIView, completionHandler: ((Bool) -> Void)) in            self.numbers.remove(at: indexPath.row)            tableView.deleteRows(at: [indexPath], with: .fade)            completionHandler(true)        }        let deleteAction = UIContextualAction(style: UIContextualAction.Style.destructive, title: "Delete", handler: handler)        // Add more actions here if required        let configuration = UISwipeActionsConfiguration(actions: [deleteAction])        configuration.performsFirstActionWithFullSwipe = true        return configuration    }}


add ui gustere recognizer to each cell, check the amount of "swipness", if its above specific threshold, do the deletion.

somthing like:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath    {        static NSString *CellIdentifier = @"identifier";        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];        if (cell == nil) {            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]];        }        UISwipeGestureRecognizer* swipe_gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];        [swipe_gesture setDirection:UISwipeGestureRecognizerDirectionLeft];        [cell addGestureRecognizer:swipe_gesture];        return cell;    }- (void)swipeLeft:(UIGestureRecognizer *)gestureRecognizer {    int threshold = 100;    if (sender.state == UIGestureRecognizerStateBegan)     {        startLocation = [sender locationInView:self.view];    }    else if (sender.state == UIGestureRecognizerStateEnded)     {        CGPoint stopLocation = [sender locationInView:self.view];        CGFloat dx = stopLocation.x - startLocation.x;        CGFloat dy = stopLocation.y - startLocation.y;        CGFloat distance = sqrt(dx*dx + dy*dy );        if (distance > threshold )        {            NSLog(@"DELETE_ROW");        }    }}


Your table view's data source has to implement

-tableView:commitEditingStyle:forRowAtIndexPath:

otherwise the built-in iOS 8 swiping functionality will not work.

This seems counterintuitive since a UITableViewRowAction accepts a block. But it's the only way I've been able to get it to work.