Я реализовал перетаскивание между двумя UICollectionViews.Иногда я получаю эту странную ошибку.
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'
Моя установка выглядит следующим образом:
- У меня есть два UICollectionViews (например, A & B)
- Переупорядочениевключен в обоих видах коллекции
- При перетаскивании элемента из A в B. Операция копируется
- При перетаскивании элемента из B в A. Операция удаляется из B. Aне выполняется.
Пока мой код выглядит следующим образом (абстрактная версия)
// 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 []
}
Шаги для повторного создания
- Имеют два UICollectionViewsс реализованными выше методами делегата
- Оба должны охватывать весь экран
- Перетащите элемент из одного и попробуйте удерживать его поверх другого в направлении края экрана, делая вид, что его уроните
- Наблюдайте за тем, как предметы реорганизуются, освобождая место для нового предмета (чтобы вы уронили предмет)
- Отведите палец от экрана и посмотрите, как он выглядит, как если бы перетаскивание было отменено.
- Заметьте, что элементы, которые были переставлены,Oom для нового элемента остается прежним.Если у вас есть консольные журналы для методов делегата макета представления коллекции, вы можете заметить, что они продолжают вызываться
- Теперь, если вы попытаетесь перетащить элемент снова или попытаться отойти от экрана, приложение вылетает.
Если у кого-нибудь из вас есть какое-либо понимание происходящего, это очень помогло бы.