NSTableViewDiffableDataSource + Drag and Drop

I was able to implement drag and drop with NSTableViewDiffableDataSource by subclassing and adding the missing methods. It works but the draggingSession willBeginAt method is never called so I can't provided a custom preview to the dragging. Any tips from AppKit developers or Apple engineers?

class ListCoordinator: NSTableViewDiffableDataSource<String, Int>, NSTableViewDelegate {

    @objc func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
        return NSPasteboardItem(pasteboardPropertyList: row.formatted(), ofType: .string)

    }

    @objc func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
        return .move
    }

    @objc func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
        ...
        return true
    }

    

    @objc func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {

        // NEVER CALLED

    }

    

}
Post not yet marked as solved Up vote post of mtsrodrigues Down vote post of mtsrodrigues
772 views

Replies

I just came across the same problem while trying to implement NSTableViewDiffableDataSource, and figured out the reason: NSTableView is misspelling the selector.

Rather than the advertised NSTableViewDataSource method tableView(_:draggingSession:willBeginAt:forRowIndexes:), the table view is instead attempting to call tableView(_:draggingSession:willBeginAtPoint:forRowIndexes:). Note that willBeginAt: is spelled willBeginAtPoint:.

I figured this out by bottlenecking responds(to:) to examine what protocol methods the table view was trying to interrogate of its data source. Implementing a method with the misspelled name makes drag & drop work as it should.

I don't know why a regular NSTableViewDataSource implementation doesn't suffer from this problem.

Besides this significant and strange bug, perhaps a larger problem is that NSTableViewDiffableDataSource was designed without any regard for drag & drop support, requiring the developer to write a springboard subclass as you, I, and surely others have had to do.

  • I can't believe that this API, which has been around for two years, is performing like this. What on earth is going on? The person who designed this API must be a genius.

Add a Comment