2012-04-25 2 views
10

Я пытаюсь реализовать перетаскивание из Finder в NSTableView моего приложения. В настройке используется контроллер NSTableView, контроллер массива, который работает как источник данных, используя привязки Cocoa к хранилищу основных данных.NSTableView и перетаскивание из Finder

я сделал следующее, в основном следующие различные посты в блоге я нашел на SO и другие сайты:

В awakeFromNib моего зрения контроллера я называю:

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

I подклассы NSArrayController и добавил следующее методы для моего подкласса (аргументация для подкласса заключается в том, что контроллер массива должен быть проинформирован о падении, поскольку он действует как источник данных в виде таблицы):

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

Моя реализация для вышеперечисленного в настоящее время только записывает в журнал, а затем возвращает логическое ДА.

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

В IB У меня есть контроллер массива, указывающий на мой пользовательский подкласс NSArrayController.

Результат: ничего. Когда я перетаскиваю PNG с рабочего стола на мой табличный вид, ничего не происходит, и файл с радостью отскакивает назад. Я должен делать что-то неправильно, но не понимаю, что. Где я иду не так?

ответ

17

Перетаскивание из Finder всегда является перетаскиванием файла, а не перетаскиванием изображения. Вам нужно будет поддерживать перетаскивание URL-адресов из 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; 
} 

Затем вам нужно извлечь URL снова когда вызывается метод tableView:acceptDrop:row:dropOperation:, создайте изображение из URL-адреса и затем сделайте что-то с этим изображением.

Даже если вы используете привязки Cocoa, вам все равно нужно назначить и реализовать объект как datasource вашего NSTableView, если вы хотите использовать методы перетаскивания. Подкласс NSTableView не принесет пользы, поскольку методы источника данных не реализованы в NSTableView.

Вам нужно только реализовать связанные с перетаскиванием методы в объекте источника данных, а не те, которые предоставляют данные таблицы, когда вы используете привязки для этого. Вы несете ответственность за уведомление контроллера массива о результате падения, вызвав один из методов NSArrayController, например insertObject:atArrangedObjectIndex:, или путем модификации массива поддержки с использованием методов доступа, соответствующих стандарту Key-Value Coding.

+0

Спасибо, но табличный вид все еще не принимает никаких перетаскиваний/капель. Любой файл, который я перетаскиваю из Finder, отскакивает назад. Я использую привязки Cocoa для привязки таблицы к ее источнику данных. – Roger

+0

Я обновил свой ответ. Вам все равно нужно реализовать объект источника данных. –