NSTableView 并从 Finder 拖放 [英] NSTableView and drag and drop from Finder

查看:9
本文介绍了NSTableView 并从 Finder 拖放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to implement drag and drop from the Finder into an NSTableView of my app. The setup uses an NSTableView, an array controller which acts as a datasource using Cocoa bindings to a Core Data store.

我做了以下,基本上是按照我在 SO 和其他网站上找到的各种博客文章:

I did the following, basically following various blog posts I found on SO and other sites:

在我的视图控制器的 awakeFromNib 中,我调用:

In the awakeFromNib of my view controller I call:

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

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

I subclassed NSArrayController and added the following methods to my subclass (the reasoning for subclassing is that the array controller needs to be informed of the drop as it acts as the datasource of the table view):

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

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

My implementation for the above currently only writes to the log and then returns a boolean YES.

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

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

In IB I have the array controller pointing to my custom NSArrayController subclass.

结果:没有.当我将一个 PNG 从桌面拖到我的表格视图上时,什么也没有发生,文件很高兴地弹回了它的原点.我一定做错了什么,但不明白是什么.我哪里错了?

Result: nothing. When I drag a PNG from the desktop onto my table view, nothing happens and the file happily bounces back to its origin. I must be doing something wrong but don't understand what. Where am I going wrong?

推荐答案

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

A drag from the Finder is always a file drag, not an image drag. You'll need to support the dragging of URLs from the Finder.

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

To do that, you need to declare that you want URL types:

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

您可以像这样验证文件:

You can validate the files like so:

 - (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 创建图像,然后对该图像执行某些操作.

You'll then need to extract the URL again when the tableView:acceptDrop:row:dropOperation: method is called, create an image from the URL and then do something with that image.

即使您使用的是 Cocoa 绑定,如果您想使用拖动方法,您仍然需要分配和实现一个对象作为 NSTableViewdatasource.子类化 NSTableView 不会有好处,因为数据源方法没有在 NSTableView 中实现.

Even though you are using Cocoa bindings, you still need to assign and implement an object as the datasource of your NSTableView if you want to use the dragging methods. Subclassing NSTableView will do no good because the datasource methods are not implemented in NSTableView.

您只需要在数据源对象中实现与拖动相关的方法,而不是在使用绑定时提供表格数据的方法.您有责任通过调用 NSArrayController 方法之一(例如 insertObject:atArrangedObjectIndex: 或通过使用符合键值编码的访问器方法.

You only need to implement the dragging-related methods in your datasource object, not the ones that provide table data as you're using bindings to do that. It's your responsibility to notify the array controller of the result of the drop, either by calling one of the NSArrayController methods such as insertObject:atArrangedObjectIndex: or by modifying the backing array using Key-Value Coding-compliant accessor methods.

这篇关于NSTableView 并从 Finder 拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆