TestsTested | ✗ |
LangLanguage | Obj-CObjective C |
License | Apache 2 |
ReleasedLast Release | Oct 2016 |
Maintained by Nevyn Bengtsson, Nevyn Bengtsson.
Depends on: | |
Cerfing | = 2.0.4 |
MeshPipe/CerfingMeshPipe | = 0.1.3 |
CoreDragon is a drag'n'drop library for iOS applications. Instead of using context menus, modal view controllers, share sheets and other "indirect manipulation" ways of moving data around, it's much more intuitive to just grab the thing you want to move, and drop it on the place where you want to move it to.
CoreDragon uses similar concepts as the drag'n' drop APIs on MacOS, and modifies them to work better in a world with view controllers. It works within a single application, and on modern iPads, between applications that are running in split screen mode.
CoreDragon was originally called SPDragNDrop, and was a Hackweek experiment written by me during the December 2012 Hackweek at Spotify. Since I really loved the idea and would hate for the code+idea to just rot away, Spotify allowed me to release the code under Apache 2.0 before my employment there ended.
pod 'CoreDragon'
to your Podfilepod install
#import <CoreDragon/CoreDragon.h>
from your bridging header, prefix header, or wherever you want to use drag'n'drop featuresBy default, CoreDragon uses a long-press-and-drag gesture to start and perform dragging. To install this default gesture, call enableLongPressDraggingInWindow:
from your Application Delegate like so:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[DragonController sharedController] enableLongPressDraggingInWindow:self.window];
return YES;
}
When you have a view that you would like to allow your users to drag, you can register it with -[DragonController registerDragSource:delegate:]
. You would probably call it from a view controller's viewDidLoad
, setting the view controller as the delegate. Whenever a dragging operation is initiated from this view, it is up to your view controller to provide the data for the object being dragged by putting it on a pasteboard:
- (void)viewDidLoad
{
[super viewDidLoad];
[[DragonController sharedController] registerDragSource:label1 delegate:self];
}
- (void)beginDragOperation:(id<DragonInfo>)drag fromView:(UIView *)draggable
{
// Required: Provide the data to be dragged by adding it to the dragging info's pasteboard:
[drag.pasteboard setValue:text forPasteboardType:(NSString*)kUTTypePlainText];
// By default, the item being dragged is represented by a screenshot of the draggable view.
// Optionally, you can set 'title', 'subtitle' and 'draggingIcon' on the dragging info
// to give it a pretty icon.
NSString *text = [(UILabel*)draggable text];
drag.title = text;
drag.draggingIcon = [UIImage imageNamed:@"testimage"];
}
Drag sources are automatically unregistered when they are deinited.
Now that the user is holding an object with their finger, they will need somewhere to drop it. You can register drop targets in a very similar manner to drag sources. The delegate protocol for drop targets has several methods:
A simple drop target could look like so:
- (void)viewDidLoad
{
[super viewDidLoad];
[[DragonController sharedController] registerDropTarget:label2 delegate:self];
}
// Ensure that we only receive drops for plain text
- (BOOL)dropTarget:(UIView *)droppable canAcceptDrag:(id<DragonInfo>)drag
{
return [drag.pasteboard containsPasteboardTypes:@[(NSString*)kUTTypePlainText]];
}
// When some plain text is dropped on this target, set the label's text to the incoming text.
- (void)dropTarget:(UIView *)droppable acceptDrag:(id<DragonInfo>)drag atPoint:(CGPoint)p
{
[(UITextView*)droppable setText:[drag.pasteboard valueForPasteboardType:(NSString*)kUTTypePlainText]];
}
A "photo frame" app with the simplest possible drag and drop support. Has a single image view which accepts drops on one tab, and another tab with a few example photos.
Features:
This is a photo organizer app with folder support, demoing all features of CoreDragon.
Photos are laid out in a collection view in a user-defined order. Dropping a photo onto another photo creates a folder. Photos can be imported from the camera roll, or dragged to the application.
Features:
TO BE IMPLEMENTED
A fake chat app with demo conversations, where you can attach photos to the conversation by dragging them from DragonPhotos. The purpose of this app is to show a real-world use case of drag&drop.
I've always loved multitouch. In addition, I love working spatially with windows and drag&drop. Neither concept has gained much traction on iPad, and not even exploring those concepts means missing out.
At Spotify, I got my windows by copying Loren Brichter's stacked panes navigation. Finally, I had tactile, direct manipulation navigation. However, all contextual operations were still performed in modes. If you wanted to share a track with a friend, you'd go into the context menu mode for your track by long-pressing it, then the sharing mode by choosing an option in a table, then the friend selection mode... To me, it would be so much more natural to just grab the track, and drag it onto the icon representing my friend. Suddenly you'd be able to remove all these modes, and have direct manipulation of your objects.
I met my hero Bret Victor at WWDC 2012, and we talked for a while about drag & drop on iPad, and he added a very important point I hadn't thought about for many years: with multitouch, you can pick something up with one hand, and navigate with the other. This concept had already blown my mind once back in 2005, when TactaPad released a few amazing concept movies and then never showed themselves again.
So during Hackweek December 2012, I mocked up drag&drop inside the Spotify iPad app. It worked really well. You could pick up a track with your right hand, tap the tab bar with your left hand, navigate around the UI a bit either by tapping on items with your left hand or springloading with your right, and dropping your item when you were done.
Unfortunately, the idea never got any traction within the company and the branch died. That was over a year ago, and the code is now uncompileable. (Yes, when your build system breaks with every point update of Xcode, code really does rot.) Thus, the only screenshot I have is of the trivial demo app in this repo. Hopefully it is inspiring enough that you now feel the immediate need to use the code or the concept in your own app! Hooray!
After WWDC 2015, when split-screen multitasking was introduced, I started working on inter-app drag'n'drop. Here's what it looked like on 20150831, and further progress on 20151129.
Inter-app drag'n'drop was released beginning of 2016, with a demo movie on Lookback.