5 Stimmen

Cocoa NSTextField Drag & Drop Erfordert Unterklasse... Wirklich?

Bis heute hatte ich noch nie die Gelegenheit, etwas anderes als ein NSWindow selbst als NSDraggingDestination zu verwenden. Wenn Sie ein Fenster als einheitliches Ziehziel verwenden, gibt das NSWindow diese Nachrichten an seinen Delegaten weiter, so dass Sie Abwürfe ohne Unterklassen von NSWindow behandeln können.

El docs sagen:

Obwohl NSDraggingDestination als informelles Protokoll deklariert ist, können die NSWindow und NSView Unterklassen Sie erstellen, um das Protokoll zu übernehmen, müssen nur nur die Methoden implementieren, die sachdienlich sind. (Die NSWindow und NSView Klassen bieten private Implementierungen für alle der Methoden.) Entweder ein Fensterobjekt oder sein Delegat kann diese Methoden implementieren; allerdings hat die Implementierung des Delegaten Implementierung hat jedoch Vorrang, wenn es Implementierungen an beiden Stellen gibt.

Heute hatte ich ein Fenster mit zwei NSTextFields darin, und ich wollte, dass sie unterschiedliche Drop-Verhalten haben, und ich wollte nicht zulassen, Tropfen irgendwo anders im Fenster. So wie ich die Dokumente interpretiere, scheint es, dass ich entweder NSTextField unterklassifizieren muss oder einige riesige Spaghetti bedingte Drop-Handler auf dem Delegaten des Fensters machen muss, der die draggingLocation gegen jede Ansicht prüft, um die verschiedenen Drop-Bereichs-Verhalten für jedes Feld auszuwählen.

Die zentralisierte NSWindow-Delegate-basierte Drop-Handler-Ansatz scheint, wie es wäre lästig in jedem Fall, wo Sie mehr als eine kleine Handvoll von Drop-Ziel Ansichten hatte. Ebenso scheint der Subclassing-Ansatz in jedem Fall mühsam zu sein, da der Code für die Drop-Behandlung jetzt in einer View-Klasse lebt, so dass man, sobald man den Drop akzeptiert hat, einen Weg finden muss, die Drop-Daten zurück zum Modell zu transportieren. Die Bindungsdokumente warnen Sie vor dem Versuch, Bindungen durch programmatisches Setzen des UI-Wertes zu steuern. So jetzt sind Sie stecken Arbeit Ihren Weg zurück um das auch.

Meine Frage lautet also: "Wirklich!? Sind das die einzigen verfügbaren Optionen? Oder übersehe ich hier etwas Unkompliziertes?"

Danke.

6voto

ipmcc Punkte 29168

Nach ein wenig mehr Forschung scheint es, dass "Ja, wirklich, Ihre zwei Optionen sind entweder Unterklasse NSTextField oder verwenden Sie Ihre NSWindowDelegate, um Tropfen zu behandeln." Ich werde weiter gehen und die Behauptung aufstellen, dass der bessere Weg von den beiden, für Garten Vielfalt Fälle von, "Ich möchte mehrere Drop-Zonen in einem einzigen Fenster" ist die NSWindowDelegate-Methode mit Hit Checks zu verwenden, da Sie das Problem der mit Ihrem Drop-Handling-Code auf der View-Seite zu vermeiden. Ich endete mit dieser draggingUpdated: Methode auf meinem Fenster Delegate-Klasse:

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

Natürlich gehört noch mehr zum Ganzen, aber dieser hitTest:-basierte Ansatz hat bei mir bisher funktioniert. Ich vermute, dass dies etwas komplexer wäre, wenn man mit einem Multi-NSCell-basierten Steuerelement wie einem NSTableView oder NSOutlineView arbeiten würde, aber es überrascht nicht, dass diese ihre eigenen Drag-Handling-Methoden haben.

Ich hoffe, das hilft jemandem weiter.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X