I have a UICollectionView
in which user can long tap and then move the items. I have implemented func invalidationContext(forInteractivelyMovingItems
and func invalidationContextForEndingInteractiveMovementOfItems
methods to handle this.
While testing on iOS 16 beta, app crashes when move an item.
Root cause is previousIndexPaths
and targetIndexPaths
both are become nil in below code. Any idea why this happens? On < iOS16 working fine.
open override func invalidationContext(forInteractivelyMovingItems targetIndexPaths: [IndexPath], withTargetPosition targetPosition: CGPoint, previousIndexPaths: [IndexPath], previousPosition: CGPoint) -> UICollectionViewLayoutInvalidationContext {
let context = super.invalidationContext(forInteractivelyMovingItems: targetIndexPaths, withTargetPosition: targetPosition, previousIndexPaths: previousIndexPaths, previousPosition: previousPosition)
//Check that the movement has actually happeneds
if previousIndexPaths.first!.item != targetIndexPaths.first!.item {
collectionView?.dataSource?.collectionView?(collectionView!, moveItemAt: previousIndexPaths.first!, to: targetIndexPaths.last!)
}
return context
}
open override func invalidationContextForEndingInteractiveMovementOfItems(toFinalIndexPaths indexPaths: [IndexPath], previousIndexPaths: [IndexPath], movementCancelled: Bool) -> UICollectionViewLayoutInvalidationContext {
return super.invalidationContextForEndingInteractiveMovementOfItems(toFinalIndexPaths: indexPaths, previousIndexPaths: previousIndexPaths, movementCancelled: movementCancelled)
}
UICollectionView
delegate method for moving item
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
if self.longPressGesture.state == .ended {
self.collectionView.reloadData()
return
}
let cell = self.availableItems[sourceIndexPath.item]
self.availableItems.remove(at: sourceIndexPath.item)
self.availableItems.insert(cell, at: destinationIndexPath.item)
}
On iOS 16 previousIndexPaths
and targetIndexPaths
are nil
On iOS 15 previousIndexPaths
and targetIndexPaths
are have values
Simply by adding a delay it works for me now on iOS 16.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
}