Reputation: 2020
I implemented a custom mechanism to perform reordering using drag and drop in a UICollectionView
, using a UILongPressGestureRecognizer
.
I have a very simple UICollectionView
with a custom UICollectionViewLayout
.
My layout class is not a subclass of UICollectionViewFlowLayout
.
Here is how it looks like:
When I start lifting a cell to begin the drag, I update a dropProposalIndexPath
property in my custom layout object so it knows which cell needs to be hidden.
My custom UICollectionViewLayout
subclass returns a UICollectionViewLayoutAttributes
with the alpha
property set to 0 for the cell which corresponds to dropProposalIndexPath
like so:
if self.dropProposalIndexPath == indexPath {
itemLayoutAttributes.alpha = 0
}
It makes the lifted cell hidden thus creating a "hole" in the UICollectionView
.
When the user moves its finger, I update the dropProposalIndexPath
property of my custom UICollectionViewLayout
subclass and invalidate its layout, then move the cell that acts as a hole at the new indexPath:
// Inform layout of the indexPath of the dropProposal
self.reorderableLayout?.dropProposalIndexPath = dropProposalIndexPath
// Move the cell
collectionView.moveItem(at: draggingIndexPath, to: dropProposalIndexPath)
Here is how it looks:
Pretty bad huh?
I implemented the exact same logic in a demo project using a subclass of UICollectionViewFlowLayout
and the transition is seamless:
I guess I'm doing something wrong or forget to do something in my UICollectionViewLayout
subclass.
I can post more code if needed.
Please note that using the built-in drag & drop mechanism (introduced with iOS 11) to perform the reordering is not an option, I want to use my custom implementation for various reasons.
Upvotes: 2
Views: 379
Reputation: 2020
In case someone encounters the same issue, the solution was to implement the following method in your UICollectionViewLayout
subclass:
func initialLayoutAttributesForAppearingItem(at: IndexPath) -> UICollectionViewLayoutAttributes?
You then return a UICollectionViewLayoutAttributes
with the alpha
property set to 0
in the initialLayoutAttributesForAppearingItem
function if the itemIndexPath
parameter matches the indexPath of your dragging cell.
Upvotes: 3