NSTableView Drag and Drop not working

2019-07-07 03:41发布

问题:

I'm trying to set up very basic drag and drop for my NSTableView. The table view has a single column (with a custom cell). The column is bound to an NSArrayController, and the array controller's content array is bound to an NSArray on my controller object. The data displays fine in the table. I connected the dataSource and delegate outlets of the table view to my controller object, and then implemented these methods:

- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard
{
    NSLog(@"dragging");
    return YES;
}

- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)op
{
    return NSDragOperationEvery;
}

- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info
              row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation
{
    return YES;
}

I also registered the drag types in -awakeFromNib:

#define MyDragType @"MyDragType"

- (void)awakeFromNib
{
    [super awakeFromNib];
    [_myTable registerForDraggedTypes:[NSArray arrayWithObjects:MyDragType, nil]];
}

The problem is that the -tableView:writeRowsWithIndexes:toPasteboard: method is never called. I've looked at a bunch of examples and I can't figure out anything I'm doing wrong. Could the problem be that I'm using a custom cell? Is there something I'm supposed to override in the cell subclass to enable this functionality?

EDIT: Confirmed. Switching the custom cell for a regular NSTextFieldCell made dragging work. Now, how do I make drag and drop work with my custom cell?

回答1:

I was banging my head against the wall in search of a more elegant solution to the same problem, and then I came across this:

http://www.wooji-juice.com/blog/cocoa-10-bindings.html

For instance, if you want to support drag-and-drop from a table, you need to set up a data source for it — even if you’re using bindings to supply the actual data, you can set a data source on it, and Cocoa needs one to handle the tableView:writeRowsWithIndexes:toPasteboard and related messages.

Yep. If you've got everything bound to your array controller, what you can do is to have the array controller implement the necessary drag/drop functions and then set the table view's data source to the array controller with setDataSource:.



回答2:

I fixed the issue. There seems to be an issue with using bindings with custom NSCells in a table view. Switching to the traditional NSTableViewDataSource methods rather than bindings and an array controller solved it.



回答3:

What works for me is to call initTextCell rather than init or initImageCell within the initializer of my custom cell (in my case, init). It doesn't seem to matter whether the superclass is NSCell or NSActionCell. Also, I have binding, and dragging still works.



回答4:

That should be sufficient to allow the drag to start. Are you sure you've connected the delegate methods?



回答5:

I ran into this problem, your custom cell needs to extend NSActionCell not NSCell if you want drag and drop to work properly. There is probably something you could implement in NSCell that would make it all work too, but I didn't dig any further after switching to NSActionCell. At least, that fixed the issue for me.



回答6:

I ran into the problem. I have a NSCell subclass, and I did implement the tableView:writeRowsWithIndexes:toPasteboard and the dataSource was set for the NSTableView. Dragging would not work.

If I set the cell type in my init for the custom subclass

    self.type = NSTextCellType;

Then I get dragging. If I don't, it defaults to NSNullCellType and dragging doesn't work. I'm guessing the people who got it working by using another subclass NSTextFieldCell works because the cell type is different.



回答7:

I also observe the similar issue, NStableView drag & drop is not working. I have 4 column in my tableview and two of them are custom cells. Dragging for non-custom cell is working fine even though its working on cell separator as well however its not working with custom cells.

My custom cell was subclassed from NSButtonCell which was causing the issue. So as suggested, I changed my parent class from NSButtonCell to NSActionCell. Now, dragging is working perfectly.

It works with both NSCell as well as NSActionCell however I required action on my cell so used NSActionCell.