2012-04-25 14 views
10

Sto cercando di implementare il trascinamento dal Finder in un NSTableView della mia app. L'installazione utilizza un NSTableView, un controller di array che funge da origine dati utilizzando i collegamenti Cocoa a un archivio dati principale.NSTableView e drag and drop dal Finder

ho fatto la seguente, in fondo seguendo vari post sul blog che ho trovato su SO e altri siti:

Nel awakeFromNib del mio controller della vista che io chiamo:

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

I sottoclasse NSArrayController e aggiunto il seguente metodi per la mia sottoclasse (il ragionamento per la sottoclasse è che il controller di array deve essere informato della caduta in quanto agisce come origine dati della vista tabella):

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

La mia implementazione per quanto sopra attualmente scrive solo nel log e quindi restituisce un valore booleano YES.

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

In IB ho il controller di array che punta alla sottoclasse NSArrayController personalizzata.

Risultato: nulla. Quando trascino un PNG dal desktop sulla mia vista tabella, non accade nulla e il file torna felicemente alla sua origine. Devo fare qualcosa di sbagliato ma non capisco cosa. Dove sto andando male?

risposta

17

Un trascinamento dal Finder è sempre un trascinamento del file, non un'immagine trascinata. Dovrai supportare il trascinamento degli URL dal Finder.

Per fare questo, è necessario dichiarare che si desidera tipi di URL:

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

è possibile convalidare i file in questo modo:

- (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; 
} 

Sarai quindi necessario estrarre nuovamente l'URL quando viene chiamato il metodo tableView:acceptDrop:row:dropOperation:, crea un'immagine dall'URL e poi fai qualcosa con quell'immagine.

Anche se si utilizzano i collegamenti Cocoa, è comunque necessario assegnare e implementare un oggetto come datasource del proprio NSTableView se si desidera utilizzare i metodi di trascinamento. La sottoclasse NSTableView non andrà bene perché i metodi dell'origine dati non sono implementati in NSTableView.

È necessario solo implementare i metodi relativi al trascinamento nell'oggetto origine dati, non quelli che forniscono dati di tabella mentre si utilizzano i collegamenti per farlo. È responsabilità dell'utente informare il controller dell'array del risultato del rilascio, chiamando uno dei metodi NSArrayController come insertObject:atArrangedObjectIndex: o modificando l'array di supporto utilizzando i metodi di accesso conformi a Key-Value Coding.

+0

Grazie, ma la vista tabella continua a non accettare alcun trascinamento/rilascio. Qualsiasi file che trascino dal Finder rimbalza ... Io uso i binding Cocoa per collegare la tabella alla sua origine dati. – Roger

+0

Ho aggiornato la mia risposta. È ancora necessario implementare un oggetto datasource. –