2012-04-25 33 views
10

我试图实现从Finder拖放到我的应用程序的NSTableView。该设置使用一个数组控制器NSTableView,该控制器充当使用Cocoa绑定到Core Data存储的数据源。NSTableView并从查找器拖放

我做了以下,基本上采取各种博客文章,我发现在SO和其他网站:

在我的视图控制器的awakeFromNib我打电话:

[[self sourcesTableView] registerForDraggedTypes:[NSArray arrayWithObjects: NSPasteboardTypePNG, nil]]; 

我子类NSArrayController的,并增加了以下方法到我的子类(子类的推理是因为它作为表视图的数据源需要通知阵列控制器):

- (BOOL) tableView: (NSTableView *) aTableView acceptDrop: (id <NSDraggingInfo>) info row: (NSInteger) row dropOperation: (NSTableViewDropOperation)operation 

我上面的实现只写入日志,然后返回一个布尔值YES。

- (NSDragOperation) tableView: (NSTableView *) aTableView validateDrop: (id <NSDraggingInfo>) info proposedRow: (NSInteger) row proposedDropOperation: (NSTableViewDropOperation) operation 

在IB我有阵列控制器指向我的自定义NSArrayController子类。

结果:没有。当我从桌面拖动一个PNG到我的表格视图时,没有任何反应,文件高兴地反弹回原点。我一定做错了什么,但不明白是什么。我哪里错了?

回答

17

Finder拖动始终是文件拖动,而不是图像拖动。您需要支持从Finder中拖动网址。

要做到这一点,你需要声明你想URL类型:

[[self sourcesTableView] registerForDraggedTypes:[NSArray arrayWithObject:(NSString*)kUTTypeFileURL]]; 

您可以验证的文件,像这样:

- (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation 
{ 
    //get the file URLs from the pasteboard 
    NSPasteboard* pb = info.draggingPasteboard; 

    //list the file type UTIs we want to accept 
    NSArray* acceptedTypes = [NSArray arrayWithObject:(NSString*)kUTTypeImage]; 

    NSArray* urls = [pb readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] 
    options:[NSDictionary dictionaryWithObjectsAndKeys: 
       [NSNumber numberWithBool:YES],NSPasteboardURLReadingFileURLsOnlyKey, 
       acceptedTypes, NSPasteboardURLReadingContentsConformToTypesKey, 
       nil]]; 

    //only allow drag if there is exactly one file 
    if(urls.count != 1) 
     return NSDragOperationNone; 

    return NSDragOperationCopy; 
} 

然后您就需要再次提取网址当调用tableView:acceptDrop:row:dropOperation:方法时,从URL创建一个图像,然后对该图像执行一些操作。

即使您使用的是Cocoa绑定,如果您想使用拖动方法,您仍然需要将对象指定为您的NSTableViewdatasource。子类化NSTableView将不会有效,因为数据源方法未在NSTableView中实施。

您只需要在数据源对象中实现与拖动相关的方法,而不是像使用绑定那样提供表数据的方法。您有责任通过调用NSArrayController方法(如insertObject:atArrangedObjectIndex:)之一或通过使用与键值编码兼容的存取器方法修改支持阵列来通知阵列控制器放置结果。

+0

谢谢,但表格视图仍然不接受任何拖放。我从Finder中拖动的任何文件都会反弹回来....我使用Cocoa绑定将表格附加到其数据源。 – Roger 2012-04-25 08:05:45

+0

我已经更新了我的答案。你仍然需要实现一个数据源对象。 – 2012-04-25 08:16:54