Ich möchte die Elternknoten meiner NSOultineView nicht sortieren.
Die Datenquelle meiner Gliederungsansicht ist ein NSTreeController.
Wenn ich auf eine Spaltenüberschrift klicke, möchte ich den Baum nur von der zweiten Ebene der Hierarchie und ihren untergeordneten Elementen sortieren und die übergeordneten Knoten in der gleichen Reihenfolge belassen.
UPDATE So binde ich Spalten an die Werte und weise den Sortierdeskriptor zu.
%Vor%Sie können einen benutzerdefinierten Vergleicher verwenden.
Um die Grundidee dieses Ansatzes zu demonstrieren, nehmen wir an, dass Sie NSTreeNode
als Ihre Baumknoten-Klasse verwenden. Alle Stammknoten sind in einem NSArray
namens content
gespeichert und Ihre drei Stammknoten sind cat
, dog
und fish
:
Dann erstellen Sie Ihren NSSortDescriptor
Prototyp. Beachten Sie, dass Sie self
als Schlüssel anstelle der zu vergleichenden Zeichenfolge (in diesem Fall representedObject
) verwenden sollten, um Zugriff auf das rohe Knotenobjekt zu erhalten. Überprüfen Sie im Vergleich, ob das Objekt in Ihrem Root-Objekt-Array enthalten ist. Wenn YES
, gib einfach NSOrderedSame
zurück, da es die Reihenfolge von der ursprünglichen Reihenfolge in deinem content
-Array unverändert lässt, ansonsten benutze die compare:
-Methode, um einen Standardvergleich durchzuführen.
Bearbeiten 2
Wenn Sie mehrere Spalten haben, die separat sortiert werden müssen, können Sie self
nicht als Schlüssel für jede Spalte verwenden, da der Schlüssel in allen Spalten sortDescriptorPrototype
s eindeutig sein sollte. In diesem Fall können Sie ein benutzerdefiniertes Objekt als representedObject
erstellen und alle Daten, einschließlich eines Zeigers, zurück auf den Baumknoten im Objekt übertragen.
Bearbeiten 1
Die Korrektheit des oben genannten Ansatzes erfordert NSOutlineView
, um seine Zeilen mit einem stable sort -Algorithmus zu sortieren. Das heißt, identische Artikel behalten immer die gleiche relative Reihenfolge vor und nach dem Sortieren. Allerdings konnte ich in der Apple-Dokumentation keinen Hinweis auf die Stabilität des hier verwendeten Sortieralgorithmus finden, obwohl meiner Erfahrung nach der obige Ansatz tatsächlich funktionieren wird.
Wenn Sie sich unsicher fühlen, können Sie Ihre Stammbaumknoten explizit vergleichen, je nachdem, ob die aktuelle Reihenfolge aufsteigend oder absteigend ist. Dazu benötigen Sie ivar
, um den aktuellen Auftrag zu speichern. Implementieren Sie einfach die outlineView:sortDescriptorsDidChange:
-Delegatenmethode:
Und ändern Sie return NSOrderedSame
zu:
Bearbeiten Sie 3
Wenn Sie aus irgendeinem Grund outlineView:sortDescriptorsDidChange:
nicht implementieren können, können Sie einen Beobachter manuell an das Array sortDescriptors des outlineView anhängen:
Auf diese Weise können Sie benachrichtigt werden, wenn der Benutzer auch auf die Kopfzeile klickt. Vergessen Sie danach nicht, die folgende Beobachtungsmethode als Teil des KVO-Prozesses zu implementieren:
%Vor% Um Speicherlecks zu vermeiden, müssen Sie diesen Beobachter entfernen, bevor outlineView
freigegeben wird (wenn nicht früher). Wenn Sie mit KVO nicht vertraut sind, lesen Sie bitte Apples Guide .
Tags und Links objective-c macos cocoa nsoutlineview