It turns out that you need to subclass NSTableViewDiffableDataSource and implement the drag and drop API in that subclass. It's kinda weird, but that is what needs to be done.
In my case, what I did was this:
-
implement all my drag and drop API that I usually would in my MyViewController
-
subclass NSTableViewDiffableDataSource to MyDiffableDataSource
-
added delegate APIs to MyDiffableDataSource that would ask the delegate for the drag and drop code. For example, it would do something like this:
| @class MyDiffableDataSource; |
| |
| |
| @protocol MyDiffableDataSourceDelegate <NSObject> |
| |
| - (nullable id <NSPasteboardWriting>)tableView:(NSTableView *)tableView |
| pasteboardWriterForRow:(NSInteger)row; |
| |
| - (void)tableView: (NSTableView *)tableView |
| draggingSession: (NSDraggingSession *)session |
| willBeginAtPoint: (NSPoint)screenPoint |
| forRowIndexes: (NSIndexSet *)rowIndexes; |
| |
| |
| - (NSDragOperation)tableView: (NSTableView *)tableView |
| validateDrop: (id <NSDraggingInfo>)draggingInfo |
| proposedRow: (NSInteger)row |
| proposedDropOperation: (NSTableViewDropOperation)dropOperation; |
| |
| |
| |
| - (BOOL)tableView: (NSTableView *)tableView |
| acceptDrop: (id <NSDraggingInfo>)draggingInfo |
| row: (NSInteger)row |
| dropOperation: (NSTableViewDropOperation)dropOperation; |
| |
| |
| |
| - (void)tableView: (NSTableView *)tableView |
| draggingSession: (NSDraggingSession *)session |
| endedAtPoint: (NSPoint)screenPoint |
| operation: (NSDragOperation)operation; |
| |
| @end |
| |
| |
| |
| @interface MyDiffableDataSource : NSTableViewDiffableDataSource |
| |
| @property (weak, nonatomic, readwrite) id <MyDiffableDataSourceDelegate> delegate; |
| |
| @end |
In the MyDiffableDataSource.m file, it would do something like this:
| - (nullable id <NSPasteboardWriting>)tableView:(NSTableView *)tableView |
| pasteboardWriterForRow:(NSInteger)row |
| |
| { |
| |
| if ([self.delegate respondsToSelector: @selector(tableView:pasteboardWriterForRow:)]){ |
| |
| return [self.delegate tableView: tableView |
| pasteboardWriterForRow: row]; |
| |
| } |
| return nil; |
| } |
| |
.
.
.
etc
I did not want to have drag and drop code in different classes, which I why I implemented step 2 and 3 using delegate messaging. Of course, I would need MyViewController to be set as the delegate of MyDiffableDataSource.
Too bad there is no real documentation that easily goes over this. You have to guess it when reading that NSTableViewDIffableDataSource conforms to NSTableViewDataSource.