I'm writing a custom view that needs to accept folder drops. The condition is: only directories are accepted, so when user drags a file nothing should happen.
I've registered my view with:
[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
And the basic dragging protocol methods are already implemented. For testing purposes:
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
{
NSLog("@Dr开发者_StackOverflow中文版ag Entered");
return NSDragOperationCopy;
}
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{
return NSDragOperationCopy;
}
- (void)draggingExited:(id<NSDraggingInfo>)sender
{
NSLog(@"Dragging Exited");
}
- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender { return YES; }
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { return YES; }
So it works almost correctly: the cursor gets a plus sign when dragging over the view. However I'd like to avoid that if the item is a regular file.
I'll probably need to do that with NSFileManager (though I wonder if there is an easier way) once I get the dragged path, but the question is where. I've tried to include the test right in the draggingEntered:
method returning NSDragOperationNone with no success. I'm following a snippet from Apple documentation:
{
NSPasteboard *pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
int numberOfFiles = [files count];
// Perform operation using the list of files
}
return YES;
}
Where should I implement this test, so the cursor stays the same if a file is dragged instead?
You should implement the test in -draggingEntered:
and return NSDragOperationNone
if the pasteboard contains a file.
However, since you have also implemented ‑draggingUpdated:
, you'll need to add the test for folder types to that method also.
At present you're always returning NSDragOperationCopy
in ‑draggingUpdated:
without testing for the file type, which means that as soon as the mouse moves inside your dragging destination, the cursor will change to a copy cursor no matter what you do in ‑draggingEntered:
.
Note that implementing ‑draggingUpdated:
is optional. If you aren't implementing a complex view with multiple possible dragging destinations then you don't need to implement it, just ‑draggingEntered:
and ‑draggingExited:
.
精彩评论