3
votes

I want to drag a file from a NSTableView row to copy it to another application (i.e. Finder). I implemented the first two steps ('Configuring Your Table View', 'Beginning a Drag Operation') of this guide and thought that would do the trick: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TableView/Tasks/UsingDragAndDrop.html

However, when I attempt to drag a row, the row text follows my mouse but the file does not copy when released. Here's what I'm sending to my UITableView upon initialization:

#define librarySongDataType @"NSFileContentsPboardType"
- (void)awakeFromNib
{
    [self setDraggingSourceOperationMask:NSUIntegerMax forLocal:YES]; // allow interapplication drags
    [self registerForDraggedTypes:[NSArray arrayWithObject:librarySongDataType] ]; // NSFileContentsPboardType
}

Here's how I'm handling the drag in my NSTableView's data source (an NSArrayController):

- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard
{
    NSLog(@"writeRowsWithIndexes");
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];
    [pboard setData:data forType:librarySongDataType];
    return YES;
}

To be clear, I'm not trying to drag files into my table view, I'm just trying to drag file(s) out of it.

1
I think you mean NSTableView. UITableView is only on the iPhone. - d11wtq
Ah, sorry, yes. I meant NSTableView. Thanks for the correction. Edited. - tassock

1 Answers

10
votes

Firstly, which document did you refer to when you wrote this line ?

 [self setDraggingSourceOperationMask:NSUIntegerMax forLocal:YES]; 

This doesn't make sense. Don't use NSUIntegerMax. Use operation masks as defined here. It's written there that NSUIntegerMax stands for everything, but you shouldn't use it; Apple may re-define the bit in the future. You should use NSDragOperationCopy or something specific. If you copied that line from a webpage or a book, you should stop trusting that book/webpage.

Secondly, forLocal: should be NO to pass the data to another application; local here means application local.

Third, instead of just setting the archived data in

 [pboard setData:data forType:librarySongDataType];

Consider making an NSFileWrapper and set it using writeFileWrapper:, see here. That way you can specify the file name to be created in Finder. Otherwise, the system doesn't have any idea what the data represent.