使用UICollectionViewDiffableDataSource和NSFetchedResultsController重新排序单元格

问题描述 投票:5回答:1

我正在使用UICollectionViewDiffableDataSourceNSFetchedResultsController将我的UICollectionView填充到我的UIViewController中。

[为了增加对单元格重新排序的能力,我添加了一个UILongPressGestureRecognizer并将其分类为UICollectionViewDiffableDataSource,以便使用它的canMoveItemAt:moveItemAt:方法。

[对单元格重新排序时,会发生以下情况:

  1. moveItemAt:被调用,并且我更新对象的位置属性并保存MOC
  2. controllerDidChangeContent:的[NSFetchedResultsControllerDelegate被调用,我从当前的fetchedObjects创建一个新快照并应用它。

[当我应用dataSource?.apply(snapshot, animatingDifferences: true)时,单元格立即切换位置。如果设置为animatingDifferences: false,它可以工作,但是所有单元格都将重新加载。这里是否有最佳实践,如何在UICollectionViewDiffableDataSourceNSFetchedResultsController上实现单元重排序?

这是我提到的方法:

// ViewController func createSnapshot(animated: Bool = true) { var snapshot = NSDiffableDataSourceSnapshot<Int, Favorite>() snapshot.appendSections([0]) snapshot.appendItems(provider.fetchedResultsController.fetchedObjects ?? []) dataSource?.apply(snapshot, animatingDifferences: animated) } // NSFetchedResultsControllerDelegate func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { createSnapshot(animated: false) } // Subclassed UICollectionViewDiffableDataSource override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { provider.moveFavorite(from: sourceIndexPath.row, to: destinationIndexPath.row) } // Actual cell moving in a provider class public func moveFavorite(from source: Int, to destination: Int) { guard let favorites = fetchedResultsController.fetchedObjects else { return } if source < destination { let partialObjects = favorites.filter({ $0.position <= destination && $0.position >= source }) for object in partialObjects { object.position -= 1 } let movedFavorite = partialObjects.first movedFavorite?.position = Int64(destination) } else { let partialObjects = favorites.filter({ $0.position >= destination && $0.position <= source }) for object in partialObjects { object.position += 1 } let movedFavorite = partialObjects.last movedFavorite?.position = Int64(destination) } do { try coreDataHandler.mainContext.save() } catch let error as NSError { print(error.localizedDescription) } }

我正在使用UICollectionViewDiffableDataSource和NSFetchedResultsController在UIViewController中填充我的UICollectionView。为了增加对单元格重新排序的能力,我添加了一个...
ios swift uicollectionview nsfetchedresultscontroller ios13
1个回答
0
投票
我对同一问题的解决方案是将UICollectionViewDiffableDataSource子类化,并在子类中实现canMoveItemAt方法以回答true。如果.ended的longPressAction情况做三件事,该动画似乎对我来说很好用:

  1. 更新模型
© www.soinside.com 2019 - 2024. All rights reserved.