UITableViewCell
swipe to delete
iOS development
Swift programming
mobile app UI

Add swipe to delete UITableViewCell

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Swipe-to-delete in UITableView is a standard iOS interaction pattern that users expect in list interfaces. UIKit provides built-in APIs for this behavior, but production code also needs data consistency, undo support, and safe async deletion flows. This guide covers modern implementations for both basic and custom swipe actions.

Basic Swipe-to-Delete With Data Source API

The classic API is tableView(_:commit:forRowAt:). When the user confirms delete, remove the model item first, then update table rows.

swift
1import UIKit
2
3final class TodosViewController: UITableViewController {
4    private var items = ["Buy milk", "Read docs", "Call team"]
5
6    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
7        items.count
8    }
9
10    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
11        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
12        cell.textLabel?.text = items[indexPath.row]
13        return cell
14    }
15
16    override func tableView(_ tableView: UITableView,
17                            commit editingStyle: UITableViewCell.EditingStyle,
18                            forRowAt indexPath: IndexPath) {
19        guard editingStyle == .delete else { return }
20
21        items.remove(at: indexPath.row)
22        tableView.deleteRows(at: [indexPath], with: .automatic)
23    }
24}

This is enough for simple local data lists.

Custom Swipe Actions With UIContextualAction

For modern UI customization, use trailing swipe actions. This enables delete plus extra actions such as archive or flag.

swift
1import UIKit
2
3final class MessagesViewController: UITableViewController {
4    private var messages = ["Invoice sent", "Build passed", "Deploy complete"]
5
6    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
7        messages.count
8    }
9
10    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
11        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
12        cell.textLabel?.text = messages[indexPath.row]
13        return cell
14    }
15
16    override func tableView(_ tableView: UITableView,
17                            trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath)
18    -> UISwipeActionsConfiguration? {
19        let delete = UIContextualAction(style: .destructive, title: "Delete") { [weak self] _, _, completion in
20            guard let self = self else { return completion(false) }
21            self.messages.remove(at: indexPath.row)
22            tableView.deleteRows(at: [indexPath], with: .automatic)
23            completion(true)
24        }
25
26        let config = UISwipeActionsConfiguration(actions: [delete])
27        config.performsFirstActionWithFullSwipe = true
28        return config
29    }
30}

This API is preferred for richer interaction design.

Keeping Model and UI in Sync

Deletion bugs usually come from updating UI and model in inconsistent order. Always mutate your source of truth first, then animate row deletion.

For diffable data sources, do not call deleteRows manually. Instead, apply an updated snapshot.

swift
var snapshot = dataSource.snapshot()
snapshot.deleteItems([itemToDelete])
dataSource.apply(snapshot, animatingDifferences: true)

Mixing diffable updates with manual row mutations can crash with invalid update exceptions.

Async Server Deletion Pattern

If deletion requires an API call, decide whether to use optimistic or pessimistic UI update:

  • optimistic: remove immediately, rollback on failure
  • pessimistic: wait for server success, then remove

Optimistic example outline:

swift
1func deleteItem(at indexPath: IndexPath) {
2    let deleted = items.remove(at: indexPath.row)
3    tableView.deleteRows(at: [indexPath], with: .automatic)
4
5    apiDelete(item: deleted) { [weak self] success in
6        guard let self = self, !success else { return }
7        self.items.insert(deleted, at: indexPath.row)
8        self.tableView.insertRows(at: [indexPath], with: .automatic)
9    }
10}

This keeps UI responsive but requires robust rollback handling.

Add Undo for Better UX

Users frequently trigger swipe delete by mistake. An undo option improves trust.

Common patterns:

  • show snackbar style message with undo action
  • support system undo manager for editable content
  • keep deleted item cached briefly before hard delete

For permanent destructive actions, also consider confirmation for sensitive records.

Accessibility and Interaction Quality

Swipe actions should remain accessible to VoiceOver users through rotor actions and explicit action buttons where appropriate. Test on smaller devices to ensure action titles remain visible and do not truncate confusingly.

Animation quality matters too. Batch updates should remain short and deterministic to avoid jank in long lists.

Common Pitfalls

  • Deleting table rows without deleting matching model entries.
  • Mixing diffable data source updates with manual row deletion APIs.
  • Capturing stale index paths in async callbacks after data changes.
  • Ignoring server failure rollback when using optimistic deletion.
  • Shipping destructive swipe actions without undo or confirmation where needed.

Summary

  • UIKit provides built-in swipe-to-delete APIs for both basic and custom behaviors.
  • Keep model updates and table updates strictly synchronized.
  • Use UIContextualAction for modern custom swipe actions.
  • Handle async deletion carefully with rollback or delayed removal strategy.
  • Add undo and accessibility support for production-quality interaction.

Course illustration
Course illustration

All Rights Reserved.