Drag and Drop Collection View cell in IOS 11 & swift 4

Drag and Drop Collection View cell in IOS 11 & swift 4

In this tutorial we are explain how to drag and drop collection view cell in two collection View at same screen in iPhone IOS 11. In IOS 11 apple introduced the Two type of protocols UICollectionViewDragDelegate and UICollectionViewDropDelegate, By the use of these protocol methods methods we can drag and drop the collection View cell from one collection View to other collection View.

NOTE:- please note that Drag-Drop supported in both iPhone and iPad, On iPad use Drag-Drop between different apps, same app, and same screen, But in iPhone use Drag-Drop only on similar screen.

First create the base project

Create the base project with two collectionView on same screen by the use of CollectionViewDataSource and CollectionViewDelegate methods. You can download the base project from here.

Now we start the Drag and drop Delegate for move the CollectionViewCell from on FirstCollectionView to SecondCollectionView.

Drag the collection view Cell (UICollectionViewDragDelegate protocol)

First we need to implement itemsForBeginning methods of drag delegate in which we need to return array of UIDragItem.

NOTE:- Must Be remember set the dragDelegate to self. And enable the dragInteraction.


1
2
3
4
5
 <span class="hljs-keyword">override</span> <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">viewDidLoad</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">super</span>.viewDidLoad()
        topCollectionView?.dragDelegate = <span class="hljs-keyword">self</span>
        topCollectionView.dragInteractionEnabled = <span class="hljs-literal">true</span>
    }

itemsForBeginning -> Provide items to begin a drag associated with a given indexPath. If an empty array is returned a drag session will not begin.
For create the UIDragItem, First we need to create NSItemProvider and that item provider pass into UIDragItem(itemProvider:)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<span class="hljs-class"><span class="hljs-keyword">extension</span> <span class="hljs-title">ViewController</span>: <span class="hljs-title">UICollectionViewDragDelegate</span> </span>{
    <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath)</span></span> -&gt; [<span class="hljs-type">UIDragItem</span>] {
        <span class="hljs-keyword">let</span> dragItem = <span class="hljs-keyword">self</span>.dragItem(forPhotoAt: indexPath)
        <span class="hljs-keyword">return</span> [dragItem]
    }
   
    <span class="hljs-comment">/// Helper method</span>
    <span class="hljs-keyword">private</span> <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">dragItem</span><span class="hljs-params">(forPhotoAt indexPath: IndexPath)</span></span> -&gt; <span class="hljs-type">UIDragItem</span> {
        <span class="hljs-keyword">let</span> imageName = <span class="hljs-keyword">self</span>.arrayFirst[indexPath.row]
        <span class="hljs-keyword">let</span> image = <span class="hljs-type">UIImage</span>(named: imageName)
        <span class="hljs-keyword">let</span> itemProvider = <span class="hljs-type">NSItemProvider</span>(object: imageName <span class="hljs-keyword">as</span> <span class="hljs-type">NSItemProviderWriting</span>)
        <span class="hljs-keyword">let</span> dragItem = <span class="hljs-type">UIDragItem</span>(itemProvider: itemProvider)
        dragItem.localObject = imageName
        <span class="hljs-keyword">return</span> dragItem
    }
}

Drop the collection view Cell (CollectionViewDropDelegate protocol)

Now first we set the CollectionViewDropDelegate to self for that collection view in which we want to drop the collectionViewCell


1
    bottomCollectionView.dropDelegate = self

Implement the method for handle the drop session for drop item. for this method DropDelegate provide the method 

1
canHandle session:

. If we not handle this methods then by default this return “YES”


1
2
3
 <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, canHandle session: UIDropSession)</span></span> -&gt; <span class="hljs-type">Bool</span> {
        <span class="hljs-keyword">return</span> session.canLoadObjects(ofClass: <span class="hljs-type">NSString</span>.<span class="hljs-keyword">self</span>)
    }

Now implement these methods for drop the item in collectionView


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)</span></span> {

        <span class="hljs-keyword">let</span> destinationIndexPath = coordinator.destinationIndexPath ?? <span class="hljs-type">IndexPath</span>(item: <span class="hljs-number">0</span>, section: <span class="hljs-number">0</span>)
        loadAndInsertItems(at: destinationIndexPath, with: coordinator)
    }
   
    <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">collectionView</span><span class="hljs-params">(<span class="hljs-number">_</span> collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?)</span></span> -&gt; <span class="hljs-type">UICollectionViewDropProposal</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-type">UICollectionViewDropProposal</span>(operation: .copy, intent: .insertAtDestinationIndexPath)
    }
   
    <span class="hljs-keyword">private</span> <span class="hljs-func"><span class="hljs-keyword">func</span> <span class="hljs-title">loadAndInsertItems</span><span class="hljs-params">(at destinationIndexPath: IndexPath, with coordinator: UICollectionViewDropCoordinator)</span></span> {
        <span class="hljs-keyword">let</span> destinationIndexPath: <span class="hljs-type">IndexPath</span>
       
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> indexPath = coordinator.destinationIndexPath {
            destinationIndexPath = indexPath
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">let</span> section = bottomCollectionView.numberOfSections - <span class="hljs-number">1</span>
            <span class="hljs-keyword">let</span> row = bottomCollectionView.numberOfItems(inSection: section)
            destinationIndexPath = <span class="hljs-type">IndexPath</span>(row: row, section: section)
        }
       
        coordinator.session.loadObjects(ofClass: <span class="hljs-type">NSString</span>.<span class="hljs-keyword">self</span>) { items <span class="hljs-keyword">in</span>
            <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> string = items <span class="hljs-keyword">as</span>? [<span class="hljs-type">String</span>] <span class="hljs-keyword">else</span> { <span class="hljs-keyword">return</span> }
           
            <span class="hljs-keyword">var</span> indexPaths = [<span class="hljs-type">IndexPath</span>]()
           
            <span class="hljs-keyword">for</span> (index, value) <span class="hljs-keyword">in</span> string.enumerated() {
                <span class="hljs-keyword">let</span> indexPath = <span class="hljs-type">IndexPath</span>(row: destinationIndexPath.row + index, section: destinationIndexPath.section)
                <span class="hljs-keyword">self</span>.arraySecond.insert(value, at: indexPath.row)
                indexPaths.append(indexPath)
            }
            <span class="hljs-keyword">self</span>.bottomCollectionView.insertItems(at: indexPaths)
        }
    }




Download the complete project here.

 

Related Post

UIPopOverPresentationController In Swift UIPopOverPresentationController UIPopOverViewController in swift is writen in swift 3.1 and Use the xcode Version 8.3.2. For use this import the Pop...
Introduction To C A Brief History Of C   C was invented and first implemented by Dennis Ritchie on a DEC PDP-11 that used the Unix operating system. C is the r...
Navigation Tab Bar in IOS | Swift tutorial Navigation Tab Bar in IOS | Swift tutorial Different Customizing techniques for Navigation bar with storyboard and code 1) Custom NavigationTabBar b...
New Tools for 64-bit Support in Xcode 9.3   New Tools for 64-bit Support in Xcode 9.3 The last macOS release to support 32-bit apps without compromise is macOS High Sierra. Make sure fu...
Loops in java Loops in JAVA Loops are used to execute a set of statements repeatedly until a particular condition is satisfied. Loop is used in programming ...
Compile C/C++ program (Dev-C/C++) what is Dev-C/C++? Dev-C/C++, developed by Bloodshed Software, is a fully featured graphical IDE(Integrated Development Environment),which ...

Leave a Reply

Your email address will not be published. Required fields are marked *

Get more stuff like this
in your inbox

Subscribe to our mailing list and get interesting stuff and updates to your email inbox.