Introduction and implementation of Drag & Drop in iOS

João Gabriel
Apple Developer Academy | Mackenzie
6 min readFeb 20, 2018

--

Tutorial

This tutorial is for those who have never implemented Drag & Drop before in an iOS application before. We are going to show you how it works and all the things you need to implement this in your application. In this tutorial, we are going to see:

- Introduction

  • What is Drag & Drop
  • How it is used in iPad and iPhone

- Creating a simple ‘KANBAN’ project with Drag & Drop

  • Presenting the ‘KANBAN’ project
  • Starting implementation of Drag & Drop into our project
  • Creating a UITableViewDragDelegate
  • Creating a UITableViewDropDelegate

Introduction

What is Drag & Drop

Drag & Drop is a new way of moving objects in iOS. It all starts with a long press on an element (image file, text and other types). The element then becomes selected, and after this we can drag the object on the screen and drop inside the application that is needing the content.

How it works in iPad and iPhone

The main difference between iPad and iPhone when using this technology is that the iPad can handle Drag & Drop between two different applications, for example if you want to select a text from the internet and drag inside your app. In iPhone, it can only handle Drag & Drop on the same application. In this tutorial we are going to tech you how to implement an Drag & Drop interaction of moving data inside the same application and from outside too.

Creating a simple ‘KANBAN’ project with Drag & Drop

Presenting the ‘KANBAN’ project

KANBAN is a nice method to organize your productivity and deal with lots of things to do during the development of a project. We just created a simple ‘KANBAN’ project that can be downloaded here:

https://github.com/joaogbp/kanban_drag_drop.git

This is a simple project with 6 UITableViews that represent all the ‘KANBAN’ parts (Sprint Backlog, ToDo, Doing, Testing, Done, and Discarded).

What we are going to learn in this tutorial is how to deal with Drag & Drop in a way that we can move the items between the columns and drag image and text content from outside the app to our table views. We created a class called “Column” to represent our table views, and a class “PostItTVCell” and “PostItImageTVCell” to represent our cells.

Implementing Drag & Drop into our project

The first thing we already created is a class with public static variables to deal with the cells that are going to be dragged. This class looks like this:

This class has an array of table views and it will also have an array of index paths just to save the initial location of each dragged cell. This class will also implements 3 methods, ‘removeAll’ will remove all the index paths of the dragging cells; ’clean’ will clean the two arrays of the class and ‘addSessionItem’ the adds a new reference to a cell.

Creating a UITableViewDragDelegate

The first thing we are going to do to implement a UITableViewDragDelegate is to create a new swift file, we are going to name it as ‘Column+Drag.swift’. We are going to create here an extension of our class ‘Column’ and it is going to extend ‘UITableViewDragDelegate’. At this point, XCode will point out that “Type ‘Column’ does not conform to protocol ‘UITableViewDragDelegate’”. You can click the ‘Fix’ button and it will create the method ‘tableView(itemsForBeginning)’.

The method ‘tableView(itemsForBeginning)’ will need to return an array of elements selected to drag, and we can implement it just by calling another helper method just like this:

As you can see, in the ‘itemsForBeginning’ method we are calling our ‘dragItem’ that will deal with the dragItem to be returned. The helper method ‘dragItem’ helps us create the itemProvider with the correct string or image content, depending on the cell we are dragging.

To enable the dragging delegate you just need to add the following code to the ‘required init’ method of the class ‘Column’:

This line will allow our Column to deal with drag.

At this point, you can run our application on an iPad (or simulator of one) and if you long press a cell it will appear bigger and ready for dragging on the screen:

As you can see, the background of the selected cell is not transparent anymore when dragging, but we want it to be transparent. To solve this, we can use the method ‘tableView(dragPreviewParametersForRowAt)’ to change the style of the cell when dragging. The code should be like this:

Now you can run our application again and see that the background color of our cell when dragging is transparent:

At this point, there is no way of getting more than one item. To solve this, we just need to implement the method ‘tableView(itemsForAddingTo)’, just like this:

It will work just as the method ‘tableView(itemsForBeginning)’ but it will be called in a different moment, when we need to add more things to our drag.

Creating a UITableViewDropDelegate

At this point, if you move a cell to another tableView, nothing happens. Let’s do some modifications on our project.

First thing we are going to do to use ‘UITableViewDropDelegate’ is to create a new XCode file called ‘Coumn+Drop.swift’. In this file we are going to create another extension for our ‘Column’ that will extend ‘UITableViewDropDelegate’. At this point XCode will once more point out that ‘Type ‘Column’ does not conform to protocol ‘UITableViewDropDelegate'' and you can click on ‘Fix’.

This function can handle the drop just if the drop location is acceptable. If our indexes.count == 0 (first if condition within addItems), we simply add in the new item, without removing it. This is because when we don’t have any index, it means that this content is coming from the outside our app. If the content is not from outside, we are going to verify if the content is from this table view, if it is we are just going to remove the first index and add to the next one. If it is not we are going to remove it from its original table view and add it to the destination one.

But we haven’t finished yet, we need to implement the following methods:

The method ‘tableView(canHandle)’ will return the type of content that will be accepted when an item is dropped, in our case it is ‘NSString’ and ‘UIImage’. Again in this method if our singleton had index.count == 0 it means that the content is from outside the app and must be copied, whereas otherwise it should just be moved from its initial poisition.

At this point, the last thing we need to do is delegate the UITableViewDropDelegate to our ‘Column’ in the method ‘required init’, with the following code:

Now it is done, I hope you enjoy :D

Tutorial produzido por: Ane Caroline Santos Gomes, João Gabriel Borelli Padilha, Osniel Lopes Teixeira

Ane Caroline Santos Gomes
João Gabriel Borelli Padilha
Osniel Lopes Teixeira

--

--