使用 UITableViewDropCoordinator 通过具有可区分数据源的 dropDelegate 为 drop 设置动画

Posted

技术标签:

【中文标题】使用 UITableViewDropCoordinator 通过具有可区分数据源的 dropDelegate 为 drop 设置动画【英文标题】:Using a UITableViewDropCoordinator to animate drops via the dropDelegate with a diffable data source 【发布时间】:2021-11-16 15:07:40 【问题描述】:

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 方法之前)。

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

以上是关于使用 UITableViewDropCoordinator 通过具有可区分数据源的 dropDelegate 为 drop 设置动画的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)