NSDraggingInfo protocol, -slideDraggedImageTo: hair-pulling woes
NSDraggingInfo protocol, -slideDraggedImageTo: hair-pulling woes
- Subject: NSDraggingInfo protocol, -slideDraggedImageTo: hair-pulling woes
- From: Mark Wright <email@hidden>
- Date: Wed, 24 Jul 2013 10:25:55 +0100
Hi all,
Has anyone, anywhere, ever, gotten -slideDraggedImageTo: to actually work as described in the docs or otherwise do anything at all?
The docs lay it out in black and white:
Slides the image to a specified location.
- (void)slideDraggedImageTo:(NSPoint)aPoint
Parameters
aPoint
A point that specifies a location in the screen coordinate system.
Discussion
This method can be used to adjust the location to which the dragged image will slide back if the drag is rejected.
It should only be invoked from within the destination’s implementation of prepareForDragOperation:, and will only have effect if the destination rejects the drag.
This method is invoked after the user has released the image but before it is removed from the screen.
This is precisely what I'm wanting to do: adjust the location to which the dragged image will slide back if the drag is rejected.
So, the key points here are:
1) The argument is in _screen coords_
2) The drag _destination_ is to be the caller
3) It must be called from within -prepareForDragOperation:
4) The destination must reject the drag (presumably by returning NO from -prepareForDragOperation:)
Given that, here's the code:
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender {
//We want to adjust the slide back point to the centre of the source's bounds.
//Importantly, reference everything to the *source* view - We're currently the destination.
NSView *sourceView = [sender draggingSource];
NSPoint adjustedSlideBackPoint = NSZeroPoint;
adjustedSlideBackPoint.x = NSMidX([sourceView bounds]);
adjustedSlideBackPoint.y = NSMidY([sourceView bounds]);
//Convert to window coords
adjustedSlideBackPoint = [sourceView convertPoint:adjustedSlideBackPoint toView:nil];
//Convert to screen coords
NSRect tmpRect = NSMakeRect(adjustedSlideBackPoint.x, adjustedSlideBackPoint.y, 0, 0);
tmpRect = [[sourceView window] convertRectToScreen:tmpRect];
adjustedSlideBackPoint = tmpRect.origin;
[sender slideDraggedImageTo:adjustedSlideBackPoint];
return NO; //<- reject the drag as per docs, doesn't slide back to our point..
//Returning YES here then returning NO from -performDragOperation to cancel the drag at the next 'step' also fails.
}
It does nothing. The drag image slides back to the starting point as normal, regardless of this code or anything else I've written.
Things I've tried that I can remember:
- Ensured the point is actually the point in screen coords I think it is - it is.
- Calling the old NSView drag method with ..slideBack:NO - no slide back at all.
- Calling the new NSView drag method - no change.
- Changing animatesToStartingPositionsOnCancelOrFail on the NSDraggingSession from YES to NO - again, no slide back at all if this is off.
- Returning NSDragOperationNone from -draggingEntered: to cancel the drag in a different location - this prevents -prepareForDragOperation: from being called at all.
- Checked that I'm deploying on 10.7 (10.8 SDK) - confirmed
- Checked 10.5 release notes and confirmed that the method is supposed to work as described from 10.5 onwards but is runtime checked and disabled on systems earlier than that.
- Searched the web - very little to no mention, in fact seemingly only a question from 2004 about it doing anything at all (it didn't back then). One question in a German forum apparently asking what I'm asking here.
- Stepping into the method instruction-by-instruction to see if it really does anything now - it seems to be checking the deployment version, asking for screens, taking an NSLock.. but that's about as far as I got because I don't know any other way than pressing the mouse click by click by click a million times on 'step into instruction', and I can't read assembly, just get the gist from the symbol names here and there alongside it.
- Perhaps it only works if the source and destination are the same object? - no difference, it doesn't do anything there either.
In thinking about all this I'm coming to the impression that something's not right here: Why would the *destination* have to implement this if it's to modify the slide back on a failure? The destination could be *anything* - a view, a window, another app, the Finder, etc. On the other hand, the destination is the only one that can call it because it's the only thing that gets passed an object conforming to the NSDraggingInfo protocol. Except in -draggingEnded:, that does actually get called on the source too. Calling the method in there does nothing either...
I'm sure I've walked this road before and given up, yet here I am again. The doc's description is so damn clear it's extremely frustrating!
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden