UITableView
iOS Development
Swipe to Delete
Edit Mode
iOS Programming

UITableView disable swipe to delete, but still have delete in Edit mode?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Sometimes an iOS screen should allow deletion only when the user explicitly enters edit mode. That avoids accidental destructive swipes while still preserving the standard delete control when the user is intentionally managing rows.

Swipe Actions and Edit Mode Are Separate Features

The first important detail is that swipe actions and edit-mode deletion are related but not identical. Disabling swipe-to-delete does not automatically remove the ability to delete in edit mode, and keeping edit-mode deletion does not require swipe gestures.

That separation is exactly what makes this UX possible.

Disable Swipe-to-Delete

To remove the normal trailing swipe action, return nil from the swipe-actions callback.

swift
1import UIKit
2
3final class ItemsViewController: UITableViewController {
4    var items = ["A", "B", "C", "D"]
5
6    override func tableView(
7        _ tableView: UITableView,
8        trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
9    ) -> UISwipeActionsConfiguration? {
10        return nil
11    }
12}

That removes the familiar destructive swipe affordance in normal mode.

Keep Delete Available in Edit Mode

To keep deletion available when the table enters editing mode, implement the usual editing callbacks.

swift
1override func tableView(_ tableView: UITableView,
2                        canEditRowAt indexPath: IndexPath) -> Bool {
3    return true
4}
5
6override func tableView(_ tableView: UITableView,
7                        editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
8    return tableView.isEditing ? .delete : .none
9}
10
11override func tableView(_ tableView: UITableView,
12                        commit editingStyle: UITableViewCell.EditingStyle,
13                        forRowAt indexPath: IndexPath) {
14    guard editingStyle == .delete else { return }
15    items.remove(at: indexPath.row)
16    tableView.deleteRows(at: [indexPath], with: .automatic)
17}

The editingStyleForRowAt method is what keeps deletion explicit: .delete only while the table is actually editing.

Add an Explicit Edit Button

A common way to enter edit mode is the built-in editButtonItem.

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    navigationItem.rightBarButtonItem = editButtonItem
4}
5
6override func setEditing(_ editing: Bool, animated: Bool) {
7    super.setEditing(editing, animated: animated)
8    tableView.setEditing(editing, animated: animated)
9}

This keeps the behavior aligned with iOS conventions and makes deletion a deliberate action instead of a casual gesture.

Diffable Data Sources Need Snapshot Updates

If the table uses a diffable data source, update the snapshot rather than calling deleteRows directly.

swift
1var dataSource: UITableViewDiffableDataSource<Int, String>!
2
3func deleteItem(_ item: String) {
4    var snapshot = dataSource.snapshot()
5    snapshot.deleteItems([item])
6    dataSource.apply(snapshot, animatingDifferences: true)
7}

That keeps the table view and the data source state synchronized.

Why This UX Choice Can Make Sense

Swipe gestures are convenient, but they are also easy to trigger by accident. Edit mode is slower and more explicit. If the deleted data is important, hard to recover, or frequently tapped during scrolling, forcing deletion through edit mode can be a good product decision.

The code is simple, but the real reason for the pattern is user intent.

Alternatives Outside Edit Mode

If the app still needs row actions outside edit mode, you do not have to bring back swipe delete. Context menus, accessory buttons, or dedicated detail screens can expose secondary actions without making destructive gestures the default interaction.

That gives the screen a safer feel without making it incapable.

Common Pitfalls

A common mistake is disabling swipe actions but forgetting to implement the edit-mode deletion callbacks. Then edit mode appears, but nothing actually deletes.

Another issue is always returning .delete regardless of whether the table is editing. That blurs the distinction between edit mode and normal mode.

Developers also sometimes update the row UI without updating the underlying data model first, which leaves the table and the backing data out of sync.

Summary

  • Disable normal swipe deletion by returning nil for trailing swipe actions.
  • Keep delete available in edit mode through the standard table-view editing API.
  • Toggle edit mode with editButtonItem or another explicit control.
  • Update the backing data model before updating the table view.
  • Use snapshot deletion instead of manual row deletion when working with diffable data sources.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.