I know that iOS 11 brings the new drag and drop functionality to collectionview but I have a completely separate issue using it. So I thought I'd try using the old way which was introduced in IOS 9 (see this link). My problem is that on iOS 11, the ending animation when your finger is removed acts weird ONLY when two cells are switched. You can see the problem in this clip.
I've been trying to figure this out for days, with no luck. It works fine on iOS 10 but not iOS 11. Any help would be appreciated.
Extra info: I'm using a collectionview with a long press gesture to initiate the reorder gesture as seen in the first link. However, the problem still occurs when using a uicollectionviewcontroller
Here's the code for the long press gesture:
func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case .began:
guard let selectedIndexPath = self.collectionView.indexPathForItem(at: gesture.location(in: self.collectionView)) else {
break
}
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))
case .ended:
// this part misbehaves on ios 11 when two cells are swapped
collectionView.performBatchUpdates({
self.collectionView.endInteractiveMovement()
)}
default:
collectionView.cancelInteractiveMovement()
}
}
To begin, you don't need to place collectionView.endInteractiveMovement()
inside of a performBatchUpdates
block. But nonetheless, this issue has been an annoyance for me as well. The discrepancy between iOS 10 and 11 with this endInteractiveMovement
things doesn't make much sense.
For my problem, I am placing a fake snapshot cell above my collectionView, and hiding the content below as I run through gesture state changes and updateInteractiveMovementTargetPosition
. Once the gesture state has .ended
, I was removing the fake cell from the superview, then performing the endInteractiveMovement
. But now with iOS 11, I was experiencing the same issue as @prolfe in the comments from the previous answer. I was getting this weird flash due to this unforeseen reload of the cell in question.
The solution I ended up going with was to place a delay on my fake cell removal, so that it kind of 'covers up' the flash.
My pushBackView
method animates the fake cell back to the drop position, then removes the fake cell. I then enact the delay:
case .ended:
fakeCellView?.pushBackView { [weak self] in // 'suppress' cell animation
DispatchQueue.main.asyncAfter(deadline: .seconds(0.01), execute: {
self?.fakeCellView?.removeFromSuperview()
})
self?.collectionView?.endInteractiveMovement()
}
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With