首页 > 解决方案 > 迅速。使用拖放在 collectionView 中一次正确地重新排序多个项目

问题描述

对于如何使用新的 ios11 拖放协议在collectionView中一次拖放多个项目(即重新排序collectionView 中的多个项目),我已经坚持了 2 周多。我无法让单元格始终正确地重新排序。

我尝试过使用占位符,但这似乎更适合远程拖动到具有异步数据加载的 collectionView 中。

我已经尝试按照博客文章中的答案中给出的说明进行操作

https://hackernoon.com/drag-it-drop-it-in-collection-table-ios-11-6bd28795b313

给出的说明(作为帖子末尾问题列表中的答案)如下

在同一个集合视图中重新排序多个项目有点乏味,需要手动处理。

首先,在从collectionView(_:dropSessionDidUpdate:withDestinationIndexPath:)返回时,在UICollectionViewDropProposal中使用UICollectionViewDropIntent作为.move UIDropOperation的.unspecified,即

func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal
{
    return UICollectionViewDropProposal(operation: .move, intent:  .unspecified)
}

其次,您需要明确处理要在集合视图中重新排序的每个项目的插入和删除。例子:

let items = coordinator.items
var dIndexPath = destinationIndexPath
if dIndexPath.row >= collectionView.numberOfItems(inSection: 0)
{
  dIndexPath.row = collectionView.numberOfItems(inSection: 0) - 1
}
var sourceIndexPaths = [IndexPath]()
var destinationIndexPaths = [IndexPath]()
for item in items
{
  if let sourceIndexPath = item.sourceIndexPath
  {
    sourceIndexPaths.append(sourceIndexPath)
    destinationIndexPaths.append(dIndexPath)
    self.items2.remove(at: sourceIndexPath.row)
    self.items2.insert(item.dragItem.localObject as! String, at: dIndexPath.row)
    dIndexPath = IndexPath(row: dIndexPath.row + 1, section: 0)
  }
}
collectionView.performBatchUpdates({
  if collectionView === self.collectionView2
  {
    collectionView.deleteItems(at: sourceIndexPaths)
    collectionView.insertItems(at: destinationIndexPaths)
  }
})

这部分有效,但仅当destinationIndexPath 小于所有拖动项目的sourceIndexPaths 时,即在5 个项目的collectionView 中,在indexPaths 3 和4 处聚集项目,并将它们插入到indexPath 1 工作并且顺序正确。但是,如果我在 indexPath 0 和 1 处聚集项目并尝试将它们放在 indexPath 4 处,它不起作用(某些项目被删除,其他项目被重复并且顺序不正确)。如果一些聚集项目的 sourceIndexPaths 小于destinationIndexPath 和其他的 sourceIndexPaths 大于 destinationIndexPath。

该作者的示例项目位于

https://github.com/pgpt10/DragAndDrop-CollectionView

有谁知道我可以如何解决这个问题。

标签: iosswiftdrag-and-dropuicollectionview

解决方案


问题是如何在调用 performBatchUpdates 之前手动删除和插入页面时在集合视图中计算正确的 indexPaths。我能够通过检查模型(collectionView 中的项目数组)并在每个循环中获取当前项目的新 indexPath 来解决问题。比手动计算每次删除和插入如何影响系统提供的后续拖动项的 indexPath 更容易


推荐阅读