iOS 11 introduced drag and drop, a feature that allows users to easily move or copy data within or between apps. With drag and drop, users can:
- Select items to drag
- Add extra items to a drag after it has started
- Transfer data asynchronously between applications
On iPads, drag and drop works within or between applications. On iPhones, drag and drop is restricted to a single app.
Drag and Drop Sample App
This post describes how the drag and drop APIs are used in a single-screen iPhone app that has users sort even and odd numbers:

To follow along, download the code for the EvenOddNumberDrag app.
Enable User Interaction
Three elements of the app’s user interface (found in Main.storyboard) are relevant to dragging and dropping:
NumberLabeldisplays the number which is to be dragged.EvenNumbersLabelis the label on which even numbers should be dropped.OddNumbersLabelis the label on which odd numbers should be dropped.
Since users will be interacting with these labels, each must have its UserInteractionEnabled property set to true. This is done in ViewController.cs:
protected void SetupDragAndDrop()
{
NumberLabel.UserInteractionEnabled = true;
EvenNumbersLabel.UserInteractionEnabled = true;
OddNumbersLabel.UserInteractionEnabled = true;
// …
}
Enable Dragging
A basic drag interaction requires only a few pieces:
- A
UIDragInteractionobject that is attached to the view that will be draggable and explicitly enabled:protected void SetupDragAndDrop() { // … var numberDragInteraction = new UIDragInteraction(this); NumberLabel.AddInteraction(numberDragInteraction); // On iPad, this defaults to true. On iPhone, this defaults to // false. Since this app should work on the iPhone, enable the // drag interaction. numberDragInteraction.Enabled = true; // … } - An
IUIDragInteractionDelegatethat acts as the delegate for the drag interaction object. In this sample,ViewControlleritself is theIUIDragInteractionDelegate. Only one of the delegate methods needs to be implemented:public UIDragItem[] GetItemsForBeginningSession(UIDragInteraction interaction, IUIDragSession session) { bool isEven = Convert.ToInt16(NumberLabel.Text) % 2 == 0; var provider = new NSItemProvider(new NSString(NumberLabel.Text)); var item = new UIDragItem(provider) { LocalObject = new NSNumber(isEven) }; return new UIDragItem[] { item } ; }This method returns an array of
UIDragItemobjects, each representing a piece of data to be included in the drag and drop operation. Each drag item contains anNSItemProviderthat holds a representation of the data to be transferred.In this case, the
NSItemProvideris given anNSString, which implements theINSItemProviderWritinginterface, one of the data representations supported byNSItemProvider.The
UIDragItemhas aLocalObjectproperty that is accessible only within the application that initiated the drag. Since this example focuses on a single app, for convenienceGetItemsForBeginningSessionsets theLocalObjectto aNSNumber. This represents whether or not the dragged number is even.
Enable Dropping
To enable a drop interaction, you will need:
- A
UIDropInteractionobject for each view on which items can be dropped:protected void SetupDragAndDrop() { // … evenDropInteraction = new UIDropInteraction(this); EvenNumbersLabel.AddInteraction(evenDropInteraction); oddDropInteraction = new UIDropInteraction(this); OddNumbersLabel.AddInteraction(oddDropInteraction); } - An
IUIDropInteractionDelegateobject. In this sample,ViewControllerserves as the drop delegate. - An implementation of the
SessionDidUpdatemethod from theIUIDropInteractionDelegateinterface extension methods:[Export("dropInteraction:sessionDidUpdate:")] public UIDropProposal SessionDidUpdate(UIDropInteraction interaction, IUIDropSession session) { UIDropProposal proposal; var isEven = (session.Items[0].LocalObject as NSNumber).BoolValue; if (interaction == oddDropInteraction && !isEven) { proposal = new UIDropProposal(UIDropOperation.Copy); } else if (interaction == evenDropInteraction && isEven) { proposal = new UIDropProposal(UIDropOperation.Copy); } else { proposal = new UIDropProposal(UIDropOperation.Forbidden); } return proposal; }This method is called any time there’s a change that will potentially affect the outcome of the drop; for example, when the drop location changes in the target view because the user has moved the item being dragged. It looks at the
IUIDropSessionto determine whether or not the drop should proceed, proposing (with aUIDropProposalcontaining aUIDropOperation) to move the dropped data, copy the dropped data, cancel the drop, or forbid the drop.In this example,
LocalObject(set up inGetItemsForBeginningSession) provides an easy way to determine whether or not the dragged number is even or odd. A copy is proposed if the potential drop is valid, and the drop is forbidden if it is invalid.Proposing a copy or forbidding a drop both add helpful icons to the dragged item:

- An implementation of the
PerformDropmethod from theIUIDropInteractionDelegateinterface extension methods:[Export("dropInteraction:performDrop:")] public void PerformDrop(UIDropInteraction interaction, IUIDropSession session) { var label = interaction == oddDropInteraction ? OddNumbersLabel : EvenNumbersLabel; session.LoadObjects(strings => { if (String.IsNullOrEmpty(label.Text)) { label.Text = strings[0]; } else { label.Text = $"{strings[0]}, {label.Text}"; } }); GenerateNumber(); }This method is used for dropping numbers on both the even bucket and the odd bucket. The drop target is determined by checking the identity of the passed-in drop interaction.
- Lastly, the
LoadObjectsmethod onIUIDropSessionfetches the data and adds it to the even or odd bucket.
Learn More
This post only scratches the surface of the iOS 11 drag and drop APIs. To dig deeper, check out the following resources:
- Xamarin documentation about Drag and Drop in iOS 11
- Drag and Drop CollectionView sample
- Drag and Drop Custom View sample
- Drag and Drop TableView sample
- Mastering Drag and Drop in iOS 11 sample
Have questions or comments about this post? Discuss them in the Xamarin forums!