2011-01-08 11 views
5

Fino ad oggi, non ho mai avuto l'occasione di utilizzare qualcosa di diverso da una NSWindow stessa come NSDraggingDestination. Quando si utilizza una finestra come destinazione di trascinamento di dimensione unica, NSWindow trasferirà tali messaggi al proprio delegato, consentendo di gestire le gocce senza sottoclasse NSWindow.Cocoa NSTextField Drag & Drop richiede sottoclasse ... Davvero?

Il docs dicono:

Anche se NSDraggingDestination è dichiarata come protocollo informale, i NSWindow e NSView sottoclassi si creati ad adottare il protocollo Basti attuazione a tali metodi che sono pertinenti. (Le classi NSWindow e NSView forniscono implementazioni private per tutti i metodi .) Un oggetto finestra o suo delegato può implementare questi metodi ; tuttavia, l'implementazione del delegato ha la precedenza se esistono implementazioni in entrambi i posti .

Oggi, ho avuto una finestra con due NSTextFields su di esso, e volevo loro di avere comportamenti goccia differenti, e non volevo permettere gocce in qualsiasi altra parte della finestra. Nel modo in cui interpreto i documenti, sembra che sia necessario sottoclassi NSTextField, o creare alcuni gestori di drop drop condizionali giganti sul delegato della finestra che hit-controlla il draggingLocation su ogni vista per selezionare i diversi comportamenti di drop-area per ogni campo.

L'approccio di drop handler centralizzato NSWindow sembra essere oneroso in ogni caso in cui si dispone di più di una piccola manciata di visualizzazioni di destinazione. Allo stesso modo, l'approccio sottoclasse sembra oneroso indipendentemente dal caso, perché ora il codice di gestione delle cadute vive in una classe di visualizzazione, quindi una volta accettato il drop devi trovare un modo per eseguire il marshalling dei dati rilasciati sul modello. Lo bindings docs ti avvisa di non provare a collegare i binding impostando il valore dell'interfaccia utente a livello di programmazione. Quindi ora sei bloccato a tornare indietro anche tu.

Quindi la mia domanda è: "Davvero !? Quelle sono le uniche opzioni prontamente disponibili? O mi sto perdendo qualcosa di semplice qui?"

Grazie.

+0

È necessario correggere l'errore di battitura nel titolo della domanda (NSTextView! = NSTextField). – NSGod

risposta

6

Dopo un po 'più di ricerca sembra che "Sì, davvero, le due opzioni sono di sottoclasse NSTextField o utilizzare NSWindowDelegate per gestire le gocce." Continuerò a sostenere che il modo migliore per i due, per i casi di varietà da giardino di "Voglio più zone di rilascio in una singola finestra" è utilizzare il metodo NSWindowDelegate con i riscontri positivi, poiché si evita il problema di avendo il codice di gestione delle cadute sul lato della vista. Ho finito con questo draggingUpdated: metodo su mia finestra classe Delegate:

- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender 
{ 
    NSPasteboard *pboard = [sender draggingPasteboard]; 
    NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; 

    if ([pboard.types containsObject: NSFilenamesPboardType] && (sourceDragMask & NSDragOperationCopy)) 
    { 
     NSView* hitView = [sender.draggingDestinationWindow.contentView hitTest: sender.draggingLocation]; 
     if (hitView && (hitView == mSourceTextField || hitView == mDestTextField)) 
     { 
      return NSDragOperationCopy;    
     } 
    } 

    return NSDragOperationNone; 
} 

Ovviamente non c'è più per l'intera immagine, ma questo hitTest: approccio basata su ha funzionato per me finora. Sospetto che ciò sarebbe leggermente più complesso se si stesse lavorando con un controllo multi-NSCell come NSTableView o NSOutlineView, ma non sorprende che questi abbiano i propri metodi di gestione del trascinamento.

Spero che questo aiuti qualcun altro.