How to suppress the prohibition mark (🚫) in UITableView drag-and-drop operations?

Question

How can I suppress this prohibition mark during this operation?

Background

I am implementing drag-and-drop functionality in a UITableView to allow users to reorder cells. During the drag operation, when a cell is dragged back to its original position, a prohibition mark (🚫) appears over the cell.

I have reviewed the API documentation for UITableViewDragDelegate and UITableViewDropDelegate, but I could not find any clear way to suppress this mark. The behavior does not impact functionality but is visually unappealing.

What I Tried

  • Customizing UITableViewDropProposal: I ensured that operation is set to .move and intent to .insertAtDestinationIndexPath. This did not resolve the issue.

  • Customizing drag preview: Using dragPreviewParametersForRowAt to set a clear background. The prohibition mark still appeared.

  • Verifying drop session: Checked the UIDropSession state in dropSessionDidUpdate to ensure valid drop handling.

Environment

  • Xcode Version: Version 16.2
  • Testing Device: iPhone 16 pro + iOS 18.2

Steps to Reproduce

Code Example

  1. Create new app with this ViewController
import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITableViewDragDelegate, UITableViewDropDelegate {

    let tableView = UITableView()
    var items = ["Item 1", "Item 2", "Item 3", "Item 4"]

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        tableView.delegate = self
        tableView.dataSource = self
        tableView.dragDelegate = self
        tableView.dropDelegate = self
        tableView.dragInteractionEnabled = true
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        tableView.separatorStyle = .none
        tableView.layer.cornerRadius = 10
        tableView.backgroundColor = UIColor.systemGray6
        view.addSubview(tableView)
        NSLayoutConstraint.activate([
            tableView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
            tableView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50)
        ])
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = items[indexPath.row]
        cell.textLabel?.textAlignment = .center
        cell.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.2)
        cell.layer.cornerRadius = 10
        cell.clipsToBounds = true
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60
    }

    func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        let dragItem = UIDragItem(itemProvider: NSItemProvider(object: items[indexPath.row] as NSString))
        dragItem.localObject = items[indexPath.row]
        return [dragItem]
    }

    func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
        guard destinationIndexPath != nil else {
            return UITableViewDropProposal(operation: .cancel)
        }
        return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
    }

    func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
        guard let destinationIndexPath = coordinator.destinationIndexPath,
              let dragItem = coordinator.items.first?.dragItem.localObject as? String else {
            return
        }

        if let sourceIndex = items.firstIndex(of: dragItem) {
            tableView.performBatchUpdates {
                items.remove(at: sourceIndex)
                items.insert(dragItem, at: destinationIndexPath.row)
                tableView.moveRow(at: IndexPath(row: sourceIndex, section: 0), to: destinationIndexPath)
            }
            coordinator.drop(coordinator.items.first!.dragItem, toRowAt: destinationIndexPath)
        }
    }
}
  1. Run simulator and start dragging a cell without moving it to a different position.

  2. Observe that a prohibition mark appears at the upper right of the cell

Any guidance would be greatly appreciated. Thank you in advance!

Answered by Claude31 in 819980022

I just added these 2 func (that allow to delete row).

No more prohibition mark.

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }

    func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

    }
Accepted Answer

I just added these 2 func (that allow to delete row).

No more prohibition mark.

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }

    func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

    }
How to suppress the prohibition mark (🚫) in UITableView drag-and-drop operations?
 
 
Q