NSTableView并从Finder中拖放

Rog*_*ger 11 cocoa finder drag-and-drop

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

我做了以下,基本上是我在SO和其他网站上发现的各种博文:

awakeFromNib我的视图控制器中,我打电话给:

[[self sourcesTableView] registerForDraggedTypes:[NSArray arrayWithObjects: NSPasteboardTypePNG, nil]];
Run Code Online (Sandbox Code Playgroud)

我将NSArrayController子类化,并将以下方法添加到我的子类中(子类化的原因是数组控制器需要被告知drop,因为它充当表视图的数据源):

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

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

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

在IB中我有数组控制器指向我的自定义NSArrayController子类.

结果:没有.当我将PNG从桌面拖到我的桌面视图上时,没有任何反应,文件很快就会弹回原点.我一定做错了什么但不明白什么.我哪里错了?

Rob*_*ger 20

来自Finder的拖动始终是文件拖动,而不是图像拖动.您需要支持从Finder中拖动URL.

为此,您需要声明您需要URL类型:

[[self sourcesTableView] registerForDraggedTypes:[NSArray arrayWithObject:(NSString*)kUTTypeFileURL]];
Run Code Online (Sandbox Code Playgroud)

您可以像这样验证文件:

 - (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;
}
Run Code Online (Sandbox Code Playgroud)

然后,您需要在tableView:acceptDrop:row:dropOperation:调用方法时再次提取URL ,从URL创建图像,然后对该图像执行某些操作.

即使您正在使用Cocoa绑定,你仍然需要分配和实施对象为datasourceNSTableView,如果你想用拖动的方法.子类化NSTableView没有用,因为数据源方法没有实现NSTableView.

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