我在两个UICollectionView之间实现了拖放。有时我会收到这个奇怪的错误。
Assertion failure in -[UICollectionView _beginInteractiveMovementForItemAtIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.54.4/UICollectionView.m:8459
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to begin reordering on collection view while reordering is already in progress'
我的设置如下,
到目前为止,我的代码如下(抽象版)
// Drop delegate
func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) {
print(#function)
let destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
self.performDrop(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
} else if collectionView.tag == CollectionView.timeline.rawValue {
// Get last index path of collection view.
let section = collectionView.numberOfSections - 1
let row = collectionView.numberOfItems(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
self.performDrop(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)
}
}
func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
print(#function)
if session.localDragSession != nil {
// Trying to drag and drop an item within the app
if collectionView.hasActiveDrag {
// Trying to re-oder within the same collection view
return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
} else {
// Trying to copy an item from another collection view
return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
}
} else {
// Trying to drag and drop an item from a different app
return UICollectionViewDropProposal(operation: .forbidden)
}
}
// Drag delegate
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
print(#function)
var item: Item?
if collectionView.tag == CollectionView.media.rawValue {
item = mediaItems[indexPath.row]
} else {
item = StoryManager.sharedInstance.timelineItems[indexPath.row]
}
if let item = item {
let itemProvider = NSItemProvider(object: item.id as NSString)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}
return []
}
重制步骤
如果你们中的任何人对正在发生的事情有任何见识,那将有很大的帮助。
答案 0 :(得分:1)
在启动新拖动时结束放置位置(UICollectionView)中的任何交互式移动都解决了我的问题。我必须按如下方式修改我的UICollectionViewDragDelegate方法,
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
var item: Item?
if collectionView.tag == CollectionView.media.rawValue {
item = mediaItems[indexPath.row]
// New line to fix the problem. 'timeline' is the IBOutlet of the UICollectionView I'm going to drop the item
timeline.endInteractiveMovement()
} else {
item = StoryManager.sharedInstance.timelineItems[indexPath.row]
// New line to fix the problem. 'media' is the IBOutlet of the UICollectionView I'm going to drop the item
media.endInteractiveMovement()
}
if let item = item {
let itemProvider = NSItemProvider(object: item.id as NSString)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}
return []
}
要解决应用程序在导航时崩溃的问题,我必须结束viewWillDisappear中的所有交互式移动。
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// 'media' and 'timeline' are the IBOutlets of the UICollectionViews I have implemented drag and drop
timeline.endInteractiveMovement()
media.endInteractiveMovement()
}
希望苹果会在将来的版本中修复此问题。
答案 1 :(得分:0)
看起来好像UICollectionViewDropDelegate
的{{1}}方法在任何人进入该“问题”时都被调用。
我认为确保在此处“结束互动运动”要好很多:
dropSessionDidEnd