Drag & Drop between UICollectionViews
So what are we building?
Screenshot from Visuel App
This post is about drag & drop, so I’ll skip the creation of table view, etc.
I assume you have two or more
UICollectionView instances, that are probably properties of some separate objects, in my case of two different
I also assume that we want to drag & drop in every direction, from one to another and back. So the implementation is the same. Again in my case, each
UITableViewCell subclass has the same implementation of
UICollectionView’s drag & drop protocols.
For context, this will be our “Database”, the shared data source between collections.
In my project I’m using Firebase Realtime Database, which can’t guarantee object order like a regular array, that’s why I’m calculating the index myself.
Note that after we update model properties, the
modelsSorted function will be returning different results.
This function is used in
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell which means that with the next reload, it will have updated state information.
The drag delegate is pretty straightforward. We will use
dragItem.localObject to pass information between collections.
We also need to make sure that if we dragged an item out of the collection, we will remove it from the original one. That information we pass in
Drop delegate is a bit longer. Mostly because of the code which calculates the new index.
Again, items are sorted from newest to oldest (
Date().timeIntervalSince1970), but we change that order when we drag and drop.
Please refer to the inline comments for explanations.
Also note, that when we perform
collectionView.performBatchUpdates, we can delete the item only if the drag & drop was within one collection. Otherwise, we pass information through
localContext to delete it from the original collection.
One extra thing that we are going to do is that we are going to highlight the area over which the user is actively dragging. We’ll do so by changing its background. This function is called continuously, so a simple timer will do the trick just fine!
If you find a mistake or have more questions, hit me up on twitter!