NSTableView并从Finder中拖放

时间:2012-04-25 00:55:06

标签: cocoa drag-and-drop finder

我正在尝试从Finder拖放到我的应用程序的NSTableView中。该设置使用NSTableView,一个数组控制器,它使用Cocoa绑定到Core Data存储区作为数据源。

我做了以下工作,基本上是在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从桌面拖到我的桌面视图上时,没有任何反应,文件很快就会弹回原点。我一定做错了什么但不明白什么。我哪里错了?

1 个答案:

答案 0 :(得分:20)

来自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,从URL创建图像,然后对该图像执行某些操作。

即使您正在使用Cocoa绑定,如果要使用拖动方法,仍需要将对象指定为datasource的{​​{1}}。子类化NSTableView将没有用,因为数据源方法未在NSTableView中实现。

您只需要在数据源对象中实现与拖动相关的方法,而不是在您使用绑定时提供表数据的方法。您有责任通过调用NSTableView方法之一(例如NSArrayController)或使用符合键值编码的访问方法修改后备阵列来通知数组控制器丢弃的结果。