JLNDragEffectManager
JLNDragEffectManager is a small, simple Objective-C class for Cocoa that gives you the morphing animation as seen when dragging controls from the palette in Interface Builder 3.
Details
I wrote a post titled “Your Very Own Drag Show with JLNDragEffectManager” with a full explanation of the design decisions, goals, and a basic video demonstration.
I later wrote a post titled “Drag Effect In Action” to demonstrate how this code is used in a real-world application, XTabulator.
Usage
- Download the source and demo project below.
- Add JLNDragEffectManager to your project.
- Add the QuartzCore to your project’s linked frameworks.
- Remember to include JLNDragEffectManager.h.
- Override the three view dragging methods.
The code below shows how to use this effect manager in your custom view. The three main drag-and-drop methods are overridden to call the manager’s corresponding methods.
{
// Let's figure out our geometry. For shits-n-giggles, we'll
// make the whole window our source screen rect, and the
// current mouse position (at start of drag) as the slide-back point
NSPoint startPointInScreen = [NSEvent mouseLocation];
NSRect sourceScreenRect = [[self window] frame];
// Let's use some images reminiscent of Interface Builder's
// drag-from-Library-palette-to-make-a-real-object effect
NSImage * insideImage = [NSImage imageNamed:@"textfieldasicon"];
NSImage * outsideImage = [NSImage imageNamed:@"textfieldrealized"];
// Don the boas and start the drag show!
[[JLNDragEffectManager sharedDragEffectManager]
startDragShowFromSourceScreenRect:sourceScreenRect
startingAtPoint:startPointInScreen
offset:NSZeroSize
insideImage:insideImage
outsideImage:outsideImage
slideBack:YES];
}
- (void)draggedImage:(NSImage *)draggedImage movedTo:(NSPoint)screenPoint
{
// Update the position
[[JLNDragEffectManager sharedDragEffectManager] updatePosition];
}
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint
operation:(NSDragOperation)operation
{
// End the drag show, clean up the glitter and sweat-and-masquera
// puddles and call it a day
[[JLNDragEffectManager sharedDragEffectManager]
endDragShowWithResult:operation];
// Do any other processing you might need, including going home to
// your cats and wig collection
// ...
}
License
This source code is free to use in any private, public, or commercial software products, with attribution. See the full license included with the source code.
Source & Demo
Projects in Which JLNDragEffectManager is Used
- XTabulator by Yours Truly
- FakeApp by Todd Ditchendorf
Use the drag effect manager in your app? Let me know and I’ll post a link.
Fantastic class, thank you very much!
One note about using it with NSTableView/NSOutlineView: these classes never call mouseDragged:, so you will need to disable Cocoa’s “slideBack” feature by adding the following code to the table view subclass. Otherwise Cocoa will slide back the invisible 1×1 drag image, and since -draggedImage:endedAt:operation: doesn’t get called until *after* the drag operation is finished, this normally adds a noticeable delay between releasing the mouse and JLNDragEffectManager’s own “slide back” animation.
event:(NSEvent *)theEvent pasteboard:(NSPasteboard *)pboard
source:(id)sourceObject slideBack:(BOOL)slideBack
{
// prevent slide back if using JLNDragEffectManager, because the
// slide back delays the call of the "end" method above
[super dragImage:anImage at:imageLoc offset:mouseOffset event:theEvent
pasteboard:pboard source:sourceObject slideBack:NO];
}
I’m glad you found it useful.
Although the slide-back issue is mentioned in both the blog post and the comments of the demo app (in DragQueenDemoView.m), you’re absolutely right that, in the case of NSTableView or NSOutlineView, you’d need to subclass and override -dragImage:at:offset:event:pasteboard:source:slideBack: to achieve the same affect. This is more or less what I did in XTabulator 2 and it works beautifully.
Thanks for writing.