Hi Dragan,
I was faced with the same issue, and came across your posting while searching for an approach. I want to drag whole-row images regardless of which column was targeted by the mouse.
Building on techniques described at https://www.mail-archive.com/cocoa-dev%40lists.apple.com/msg108722.html (for some reason this web app won't let me format that as a link) and here, I came up with this:
func tableView(_ tableView: NSTableView,
draggingSession session: NSDraggingSession,
willBeginAt screenPoint: NSPoint,
forRowIndexes rowIndexes: IndexSet) {
session.enumerateDraggingItems(options: .concurrent,
for: nil,
classes: [NSPasteboardItem.self],
searchOptions: [:]) { (draggingItem, index, stop) in
// Get the row index for this drag item. Could cheat and map `index` to `rowIndexes`, but this is cleaner.
guard let pasteboardItem = draggingItem.item as? NSPasteboardItem,
let rowIndex = pasteboardItem.propertyList(forType: "com.example.RowIndexPasteboardType") as? Int else {
stop.pointee = true
return
}
// Compensate for the dragged column offset.
let dragPointInWindow = tableView.window!.convertPoint(fromScreen: screenPoint)
let dragPointInView = tableView.convert(dragPointInWindow, from: nil)
let columnIndex = tableView.column(at: dragPointInView)
let columnRect = tableView.rect(ofColumn: columnIndex)
draggingItem.draggingFrame.origin.x -= columnRect.origin.x + 7 // The 7px error is a mystery to me (on 12.6 at least).
// Register a provider that will render a bitmap image of the whole row.
draggingItem.imageComponentsProvider = {
guard let rowView = tableView.rowView(atRow: rowIndex, makeIfNecessary: false),
let imageRep = rowView.bitmapImageRepForCachingDisplay(in: rowView.bounds) else {
return []
}
imageRep.size = rowView.bounds.size
rowView.cacheDisplay(in: rowView.bounds, to: imageRep)
let image = NSImage(size: rowView.bounds.size)
image.addRepresentation(imageRep)
let component = NSDraggingImageComponent(key: .icon)
component.contents = image
component.frame.size = image.size
return [component]
}
}
}
It seems to work well enough, and is implemented in the data source (no subclassing required). How's it grab ya?