Kev*_*ark 6 datasource ios swift
我正在尝试UICollectionViewDropDelegate使用 DiffableDataSource (在 iOS 13 中引入)来实现。
UICollectionViewDragDelegate,效果很好。collectionView.dropDelegate = selffunc collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)(你甚至可以在方法为空的情况下尝试)。该应用程序将构建并运行,但一旦您开始拖动单元格,该应用程序就会立即崩溃并显示以下消息:
由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“当充当 UICollectionView 的数据源时,UICollectionView 必须通过 UICollectionViewDiffableDataSource API 进行更新:请不要直接在 UICollectionView 上调用突变 API。
所以看起来这个方法正在尝试直接修改 UICollectionView (也许在移动项目时移动单元格?)我不知道如何绕过这种行为。
想法?
这是一个相当简单的解决方案。从UICollectionViewDropDelegate函数performDropWith开始。请注意,我只需要一个 .move 而不需要 .copy,但您只需添加一个 copyItems() 方法,类似于下面的 reorderItems() 方法:
func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) {
var destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
} else {
let section = collectionView.numberOfSections - 1
let row = collectionView.numberOfItems(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
}
switch coordinator.proposal.operation {
case .move:
self.reorderItems(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
break
case .copy:
// Not copying between collections so this block not needed.
return
default:
return
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们需要函数 reorderItems() 来处理 collectionView 中的实际更改。需要明确的一件事是,快照 (NSDiffableDataSourceSnapshot<>) 和数据源 (UICollectionViewDiffableDataSource<>) 都是类变量。
/// reorderItems method
/// This method moves a cell from the sourceIndexPath to the destinationIndexPath within the same UICollectionView
///
/// - Parameters:
/// - coordinator: UICollectionViewDropCoordinator obtained in performDropWith
/// - destinationIndexPath: IndexPath where user dropped the element.
/// - collectionView: UICollectionView object where reordering is done.
private func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView) {
let items = coordinator.items
if items.count == 1, let item = items.first, let sourceIndexPath = item.sourceIndexPath {
var destIndexPath = destinationIndexPath
if destIndexPath.row >= collectionView.numberOfItems(inSection: destIndexPath.section) {
destIndexPath.row = collectionView.numberOfItems(inSection: destIndexPath.section) - 1
}
/// Since my collectionView data is attributed to a Firebase.storage set of data, this is where I write my changes back to the store.
snapshot.moveItem(dataSource.itemIdentifier(for: sourceIndexPath)!, beforeItem: dataSource.itemIdentifier(for: destinationIndexPath)!)
dataSource.apply(snapshot, animatingDifference: true)
coordinator.drop(items.first!.dragItem, toItemAt: destIndexPath)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4004 次 |
| 最近记录: |