Is it necessary to subclass NSTableView or NSTableCellView to create a custom drag image when the tableView is the drag source?
If not, what is the magic method I am missing to do this? I cannot seem to find anything solid.
NSTableCellView subclasses have can (slightly mysteriously) override:
@property(retain, readonly) NSArray *draggingImageComponents
(array of NSDraggingImageComponent instances that will get composited together (who knows in what fashion they get composited...))
NSTableView itself has
- (NSImage *)dragImageForRowsWithIndexes:(NSIndexSet *)dragRows tableColumns:(NSArray *)tableColumns event:(NSEvent *)dragEvent offset:(NSPointPointer)dragImageOffset
But these are indeed subclassing options it seems.
Anybody know another technique here?
(10.8+ is target )
It looks as if NSTableViewCell
@property(retain, readonly) NSArray *draggingImageComponents
does not get called automatically but must be explicitly referenced for view based table views. -draggingImageComponents
can be overridden to supply the components used to composite the drag image.
- (void)tableView:(NSTableView *)tableView draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint forRowIndexes:(NSIndexSet *)rowIndexes
{
// configure the drag image
// we are only dragging one item - changes will be required to handle multiple drag items
BPPopupButtonTableCellView *cellView = [self.columnsTableView viewAtColumn:0 row:rowIndexes.firstIndex makeIfNecessary:NO];
if (cellView) {
[session enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
forView:tableView
classes:[NSArray arrayWithObject:[NSPasteboardItem class]]
searchOptions:nil
usingBlock:^(NSDraggingItem *draggingItem, NSInteger idx, BOOL *stop)
{
// we can set the drag image directly
//[draggingItem setDraggingFrame:NSMakeRect(0, 0, myWidth, myHeight) contents:myFunkyDragImage];
// the tableview will grab the entire table cell view bounds as its image by default.
// we can override NSTableCellView -draggingImageComponents
// which defaults to only including the image and text fields
draggingItem.imageComponentsProvider = ^NSArray*(void) { return cellView.draggingImageComponents;};
}];
}
}
In your data source you'll want to set the images e.g. from your tableView:draggingSession:willBeginAtPoint:forRowIndexes:
method like so
[session enumerateDraggingItemsWithOptions:NSDraggingItemEnumerationConcurrent
forView:tableView
classes:[NSArray arrayWithObject:[NSPasteboardItem class]]
searchOptions:nil
usingBlock:^(NSDraggingItem *draggingItem, NSInteger index, BOOL *stop)
{
[draggingItem setDraggingFrame:NSMakeRect(0, 0, myWidth, myHeight)
contents:myFunkyDragImage];
}];