如何使用拖放重新排序 UITableView?

DPM*_*itu 3 uitableview uikit ios

我知道拖放可用于在整个应用程序和应用程序之间传输数据。我对此不感兴趣。我想要的只是使用拖放功能来重新排序表视图而不传输数据。我怎么做?

小智 10

我发现这个问题的答案确实令人困惑,并且发现实施UITableViewDragDelegate并不是这里所需要的。基本上:

  • 如果您只想能够使用拖放对表视图重新排序,则不要实现UITableViewDragDelegate,而只需实现func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)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)
}
Run Code Online (Sandbox Code Playgroud)
  • 否则,如果您希望能够在应用程序或视图等之间拖放项目,那么您将需要实现UITableViewDragDelegate和 随之而来的方法,例如,
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem]{
    // Handle here
}
Run Code Online (Sandbox Code Playgroud)

func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
    // Handle Drop Functionality
}
Run Code Online (Sandbox Code Playgroud)

等等。不会对此进行太多详细介绍,但您会在其他地方找到有关在不同视图和应用程序之间拖放的教程。但是,对于使用拖放对表格视图单元格进行简单的重新排序,请使用第一个选项并且不要实现UITableViewDragDelegate.

希望这对我有帮助,因为我对这两种方法有点困惑。

  • 但如果我选择第一个选项,我就无法长按重新排列。 (4认同)

DPM*_*itu 9

如果您在本地单个项目执行拖动,则可以使用tableView(_:moveRowAt:to:). 为此,您需要实现UITableViewDragDelegate

设置

首先设置您的代表。dragInteractionEnablediPhone 需要设置。

func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    tableView.delegate = self
    tableView.dragDelegate = self
    tableView.dragInteractionEnabled = true
}
Run Code Online (Sandbox Code Playgroud)

UITableViewDragDelegate

请注意,该数组正在返回单个项目。如果您返回多个项目,则将使用这些UITableViewDropDelegate方法而不是tableView(_:moveRowAt:to:)。您必须设置一个本地对象。

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

移动

这是移动发生的地方,实际上是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)
}
Run Code Online (Sandbox Code Playgroud)

如果需要,您也可以使用tableView(_:canMoveRow:at:) tableView(_:targetIndexPathForMoveFromRowAt: toProposedIndexPath:)

你可以在这里阅读更多...

  • 谢谢!指出一件事(非常欢迎您为我澄清):我还使用“canMoveRow:at:”和“targetIndexPathForMoveFromRowAt:toProposedIndexPath:”,当我使用“itemsForBeginning:forSession”的实现时,我得到了奇怪的行为:atIndexPath`(它将允许拖动不应该移动的项目)——只需返回一个空数组即可为我修复它。 (2认同)