Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Drag and Drop to reorder a UITableView?

I know that drag and drop can be used to transfer data throughout and between apps. I'm not interested in that. All I want is to use drag and drop functionality to reorder a table view without transferring data. How do I do that?

like image 677
DanubePM Avatar asked Dec 01 '22 09:12

DanubePM


1 Answers

If you are performing a drag on a single item locally, you can use tableView(_:moveRowAt:to:). In order to do this, you need to implement UITableViewDragDelegate.

Setup

Start by setting your delegates. Setting dragInteractionEnabled is required for iPhones.

func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    tableView.delegate = self
    tableView.dragDelegate = self
    tableView.dragInteractionEnabled = true
}

UITableViewDragDelegate

Notice that the array is returning a single item. If you return more than one item, then the UITableViewDropDelegate methods will be used instead of tableView(_:moveRowAt:to:). You must set a local object.

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

Moving

This is where the moving happens and is actually a part of UITableViewDelegate.

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    // Update the model
    let mover = data.remove(at: sourceIndexPath.row)
    data.insert(mover, at: destinationIndexPath.row)
}

You can also use tableView(_:canMoveRow:at:) and tableView(_:targetIndexPathForMoveFromRowAt: toProposedIndexPath:) if needed.

You can read more here...

  • Drag and Drop
  • Adopting Drag and Drop in a Table View
like image 177
DanubePM Avatar answered Dec 05 '22 10:12

DanubePM