使用NSTableView作为拖动源时自定义拖动图像

6
需要在tableView作为拖动源时创建自定义拖动图像,是否有必要子类化NSTableView或NSTableCellView?
如果不需要,我缺少的神奇方法是什么?我似乎找不到任何可靠的东西。
NSTableCellView子类可以(有点神秘地)重写:
@property(retain,readonly)NSArray *draggingImageComponents (一组NSDraggingImageComponent实例,将会被合成在一起(谁知道它们以什么方式被合成...))
NSTableView本身具有
- (NSImage *)dragImageForRowsWithIndexes:(NSIndexSet *)dragRows tableColumns:(NSArray*)tableColumns event:(NSEvent *)dragEvent offset:(NSPointPointer)dragImageOffset
但这些似乎确实是子类化选项。
有人知道这里还有其他技巧吗? (目标为10.8+)

在进一步的测试中,首先从NSTableCellView开始(最简单的路径!)似乎尽管它们提供了一个图像,但它首先经过表视图,而表视图会根据其剪辑视图对拖动图像进行一些奇怪的处理...当拖动开始时,在剪辑视图中不可见的任何内容都不是拖动图像的一部分。 - uchuugaka
2个回答

4
似乎是 NSTableViewCell
@property(retain, readonly) NSArray *draggingImageComponents

对于基于视图的表视图,-draggingImageComponents不会自动调用,但必须明确引用。可以重写-draggingImageComponents以提供用于组合拖动图像的组件。

- (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;};
         }];
    }
}

2
在你的数据源中,你需要设置图片,例如在你的`tableView:draggingSession:willBeginAtPoint:forRowIndexes:`方法中这样做。请参考此链接
   [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];
    }];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接