2012-04-25 68 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