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
- 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)
}
}
}
-
Run simulator and start dragging a cell without moving it to a different position.
-
Observe that a prohibition mark appears at the upper right of the cell
Any guidance would be greatly appreciated. Thank you in advance!
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) {
}