1

在 iOS 11 中,Apple 向 TableViews 引入了原生拖放功能,它为常见的拖放交互提供了特定的动画。假设您返回了正确的 UIDropProposal 它会很容易地在表格视图中为重新排序的放置设置动画

func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
  // usual code to handle drop, get dragItem, etc
  // ....

  // update the dataModel to reflect the change
  self?.model.updateDataSourceForDrag(from: sourceIndexPath, to: destinationIndexPath)

 // perform the drop animation with the drop coordinator
 coordinator.drop(dragItem, toRowAt: destinationIndexPath)
}

这将很好地动画将放置的项目插入 tableView 到它悬停的间隙中。

快进到 iOS 13+ 和 diffable 数据源的使用,我在 Apple 文档中找不到使用带有快照的 dropCoordinator 的参考,并且没有更新指南、教程或 WWDC 视频来展示如何组合两组 API。

拖放控制器将在拖动操作期间正确“管理” tableView 并移动单元格以显示拖动单元格将下降的间隙,但它不会使用coordinator.drop(dragItem, toRowAt: destinationIndexPath).

我目前的解决方法是手动更新然后应用快照:

DispatchQueue.main.async {
  var snapshot = self?.dataSource.snapshot()
  if destinationIndexPath.row > sourceIndexPath.row {
     snapshot?.moveItem((self?.dataSource.itemIdentifier(for: sourceIndexPath))!, afterItem: (self?.dataSource.itemIdentifier(for: destinationIndexPath))!)
  } else {
     snapshot?.moveItem((self?.dataSource.itemIdentifier(for: sourceIndexPath))!, beforeItem: (self?.dataSource.itemIdentifier(for: destinationIndexPath))!)
  }
  self?.dataSource.apply(snapshot!, animatingDifferences: false)
}

这在一定程度上有效,但它没有与放置控制器动画集成。因此,当我拖动时,我可以获得在 tableView 中提供放置间隙的动画,但是一旦我放下它,单元格就会从其原始 indexPath 移动而不是从动画放置的项目移动(正如我所期望的这种解决方法),这是都相当笨重。

dropCoordinator 可以使 tableView 为拖动设置动画,这表明它也应该能够为 drop 设置动画,但我找不到实现这一点的方法。

任何这方面的经验都将不胜感激(在我放弃并将代码恢复为旧的 UITableViewDataSource 方法之前)。

4

1 回答 1

0

放置动画现在可以在几个月未修改的代码上按预期工作。

iOS14 和 iOS15 的早期版本中一定存在一个错误,该错误已在最近的一次更新中得到修复。

所有这些都浪费了时间和精力。有时我们真的应该对自己的代码更有信心。

于 2022-02-08T19:44:08.490 回答