Reputation: 3383
I'm implementing drag and drop in a table view, and the problem I'm having is that the drag image is always based on the column where the drag started, but I want to use the image from the first column.
I looked at Apple's TableViewPlayground sample, where the "Complex OutlineView Window" does what I want, but I can't figure out what I'm doing different in terms of setting up the drag.
I put together a simple example at https://github.com/Uncommon/TableTest - if you drag from the second column where it says "stuff", then it looks like you're dragging the word "stuff". What I want is to have the drag image always come from the first column (with the icon and name) regardless of which column you drag from.
In my data source I implement tableView(tableView:,pasteboardWriterForRow:)
to enable dragging, but that doesn't include information about what column the drag started in. What am I missing from the example app to make this work?
Upvotes: 1
Views: 564
Reputation: 17
In response to why
dragImageForRows(with:tableColumns:event:offset:)
didn't work:
From the Apple documentation:
Note: To support multi-item drags, it is highly recommended to implement the delegate method tableView:pasteboardWriterForRow: instead. Using that method will cause this method to not be called.
Upvotes: 1
Reputation: 211
The accepted answer didn't work for me. Instead, I had to implement the following optional function in NSTableViewDataSource
:
func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {
// Or whatever cell you want as the drag image
let cell = tableView.view(atColumn: 0, row: rowIndexes.first!, makeIfNecessary: false) as? NSTableCellView
session.enumerateDraggingItems(options: .concurrent, for: nil, classes: [NSPasteboardItem.self], searchOptions: [:]) {(draggingItem, idx, stop) in
if let cell = cell {
let rect = cell.bounds
let drag = session.draggingLocation
// You can customize the image starting point and size here
draggingItem.setDraggingFrame(NSRect(x: drag.x, y: drag.y, width: rect.width, height: rect.height), contents: cell.draggingImageComponents)
draggingItem.imageComponentsProvider = {
return cell.draggingImageComponents
}
}
}
}
Credit goes to this answer for providing much of this solution.
Upvotes: 4
Reputation: 15587
NSTableView
drags the column where the drag started, NSOutlineView
drags the outline column. If you want to change the image, subclass NSTableView
and override dragImageForRows(with:tableColumns:event:offset:)
.
Upvotes: 0