UIContextMenuConfiguration : UI Bug due to cell recycling at the deletion of an item in an UICollectionView

Feedback assistant ID: *****

Description

On
iOS 13+, when we delete an item of a UICollectionView after presenting a contextual menu with the new API collectionView(_:contextMenuConfigurationForItemAt:point:), there is a bug that briefly display a wrong cell. This bug is particularly visible on an horizontal scroll UICollectionView**.

Step by step

  • my app display an horizontal scroll UICollectionView

  • i display the contextual menu with a long press on the item at indexPath(0:3)

  • i delete the item at indexPath(0:3)

  • the delete animation is triggered

  • the cell at indexPath(0:6) (before the delete) appears briefly

  • the cell at indexPath(0:4) (before the delete) takes place at indexPath(0:3)

What results I expected

I expected that the deletion does not briefly display a wrong cell.

What results I actually saw

A wrong cell appears briefly during the deletion.

Conclusion

Has anyone come across this problem before ? What solution did you apply?

Thanks.
If you mutate the underlying collection view in one of the menu's actions, you're responsible for providing the menu with an updated dismissal preview using the delegate's previewForDismissingContextMenuWithConfiguration method (https://developer.apple.com/documentation/uikit/uicollectionviewdelegate/3295918-collectionview).

Since the preview can represent any arbitrary view, you can either return a different cell (if the modification was a move) or an empty or 0 alpha view so the menu fades out. In iOS 14.0, returning a nil preview causes the menu to shrink down and fade out. If you're using UICollectionViewDiffableDataSource, the dismissal preview is updated automatically in response to data source modifications.
Providing the next cell after the deletion in the previewForDismissingContextMenuWithConfiguration method seems to solve the problem but how can I retrieve the action identifier (or another information) that trigger the dismiss ?

How to know if the user choose "delete" or just "cancel" the contextual menu inside the previewForDismissingContextMenuWithConfiguration method ?
How to provide the current cell in case of a "cancel" and the next cell in case of a delete ?

Thank you for your help.
If the exact nature of the action varies, this is something you'll likely have to keep track of yourself. However, if you only need to know whether the originally previewed cell is still present, you can do this by ensuring you give your UIContextMenuConfiguration a unique identifier that you can always associate with the data that backs the cell. Since the action is executed before the menu dismisses, you'll be able to check for the presence of your backing data in previewForDismissingContextMenuWithConfiguration, and return a different preview if the item has been deleted.
After a lot of tests, providing the next cell after the deletion in the previewForDismissingContextMenuWithConfiguration method solves the problem that a wrong cell is briefly displayed during the deletion but its create a new UI Bug with the menu.

Indeed, during the dismiss of the menu, the menu quickly moves below the next cell.
Could you please open a feedback ticket for this and ideally attach a video and a sample project? As long as you are using UICollectionView's convenience APIs instead of maintaining your own context menu interaction this should just-work™. If it doesn't this might be a UIKit bug.
I already open a feedback for the problem that I describe in my first post with the same informations + a demo project.

Note that this bug is visible on the Apple Photos application (first tab) when you delete a photo in the grid using the contextual menu on iPad.


I have a similar issue with a UICollectionView fed by a UICollectionViewDiffableDataSource that receives apply calls with data coming from a NSFetchedResultsController. With this configuration, even when I return nil from previewForDismissingContextMenuWithConfiguration, when a record is deleted from the context menu the animation still fades first into the same cell and sometimes it's replaced with a blank cell briefly. I guess this issue is probably because the (asynchronous) indirection of the delete action. But how can I solve this problem?
UIContextMenuConfiguration : UI Bug due to cell recycling at the deletion of an item in an UICollectionView
 
 
Q