Article

Making a View into a Drag Source

Adopt drag interaction APIs to provide items for dragging.

Overview

By implementing a drag interaction delegate (UIDragInteractionDelegate) for a view, you enable that view to function as a drag source in your app.

Enable a View as a Drag Source

Any instance or subclass of UIView can act as a drag source. Your first steps to make this happen are:

  1. Create a drag interaction (a UIDragInteraction instance).

  2. Specify the drag interaction’s delegate (an object that conforms to the UIDragInteractionDelegate protocol).

  3. Add the interaction to the view’s interactions property.

Here’s how to do this using a custom helper method, which you would typically call within a view controller’s viewDidLoad() method:

func customEnableDragging(on view: UIView, dragInteractionDelegate: UIDragInteractionDelegate) {
    let dragInteraction = UIDragInteraction(delegate: dragInteractionDelegate)
    view.addInteraction(dragInteraction)
}

Create a Drag Item

A drag item encapsulates a source app’s promises for providing a variety of data representations for one model object.

To create a drag item, implement the dragInteraction(_:itemsForBeginning:) method in your drag interaction delegate, as shown here in a minimal form:

func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
    // Cast to NSString is required for NSItemProviderWriting support.
    let stringItemProvider = NSItemProvider(object: "Hello World" as NSString)
    return [
        UIDragItem(itemProvider: stringItemProvider)
    ]
}

This implementation uses the init(object:) convenience initializer. When you instantiate a drag item, pass an object in your app’s native representation, or in the highest-fidelity representation you support. In general, ensure that the first element in the item provider’s registeredTypeIdentifiers array represents the highest-fidelity data your drag interaction delegate can deliver.

To add more data representations to a drag item, as you typically would in your app, add them in fidelity order, from highest to lowest. When adding representations, you have choices:

  • The best option for adding multiple data representations to a drag item, in many cases, is to adopt the NSItemProviderWriting protocol in your model class. Using this protocol, you place the code for providing multiple data representations within the model class.

  • You can use the registerObject(_:visibility:) method, or related methods, from the NSItemProvider class, to explicitly register data representations.

Understand a Drag Source in Context

In the dragInteraction(_:itemsForBeginning:) protocol method, your source app responds to a request from the system. This request is itself triggered by the user starting to drag an item in your app’s UI. The conversation between your app and the system proceeds as shown here:

APIs for providing drag items from a drag source

The figure above depicts the steps for constructing a drag item, in context:

  1. The user initiates a drag activity with a long press on a view in your app, followed by moving their finger while still touching the screen. The system instantiates a drag session (an object that conforms to the UIDragSession protocol, not shown in the figure) for managing the drag activity.

  2. The system calls the drag interaction delegate’s dragInteraction(_:itemsForBeginning:) protocol method. Your delegate returns one or more drag items.

  3. Finally, the system populates the drag session with your drag items, ready for the user to move the drag session to a destination.

See Also

First Steps

Understanding a Drag Item as a Promise

Use drag items to convey data representation promises between a source app and a destination app.

Making a View into a Drop Destination

Adopt drop interaction APIs to selectively consume dragged content.

Adopting Drag and Drop in a Custom View

Demonstrates how to enable drag and drop for a UIImageView instance.

Adopting Drag and Drop in a Table View

Demonstrates how to enable and implement drag and drop for a table view.