2009-07-14 2 views
6

Ich habe eine Ansicht, die in jedem meiner CollectionView-Elemente verwendet wird. Ich habe ein IBOutlet zu dem CollectionViewItem aus meiner Sicht und ich habe das in Interface Builder angeschlossen. Ich möchte auf einen Wert von dem reprodedObject (das ein Core Data-Objekt ist) in meinem Ansichtscode zugreifen. Hier ist ein Beispiel dafür, was ich versuche zu tun - eine Sequenz Wert des representedObject zuzugreifen:Wie bekomme ich das reprodedObject aus einer Sicht in einem NSCollectionViewItem?

In der H-Datei:

IBOutlet NSCollectionViewItem *item; // Connected in IB 

In der .m-Datei

NSString *seq = [[item representedObject] valueForKey:@"seq"]; 
NSLog(@"Seq: %@", seq); // returns Seq: (null) 

Ich weiß, dass der Seq aufgefüllt ist, da ich es in IB mit dem Schlüsselpfad representObject.seq zu einem Label in der CollectionViewItem-Ansicht gebunden habe und das funktioniert.

Irgendeine Idee warum, wenn ich versuche, auf den Wert für seq im Code für die Ansicht zuzugreifen, gibt es Null zurück?

Antwort

1

Es ist sehr wahrscheinlich, dass NSCollectionViewItem nicht über IBOutlet-Verbindungen von den Ansichten ihres Elements zum Prototyp NSCollectionViewItem kopiert. Daher ist item null, also seq wird auch Null sein.

Das typische Muster für den Zugriff auf die NSCollectionViewItem-Instanz besteht in der Bindung an den Prototyp. Sie erwähnen, dass Sie das getan haben und dass es funktioniert. Das liegt einfach daran, dass dies der typische, unterstützte Weg ist.

Wenn Sie wirklich eine Verbindung direkt zu dem Element benötigen, die Bindungen nicht bieten können, müssen Sie wahrscheinlich manuell einrichten. Eine Möglichkeit besteht darin, NSCollectionViewItems -copyWithZone: zu überschreiben, super aufzurufen und dann die Verbindung manuell herzustellen.

+0

Danke, das hat den Trick gemacht. – Austin

+1

Ich bin verwirrt von dieser Antwort. Zuerst gibt @kperryua Folgendes an: "Das typische Muster für den Zugriff auf die NSCollectionViewItem-Instanz besteht darin, sich an den Prototyp zu binden. Sie erwähnen, dass Sie dies getan haben und dass es funktioniert." Aber @ Austins Frage erwähnt nur die Verwendung des Schlüsselworts "representObject.seq" und in der Tat ist es schwer zu sehen, wie man den itemPrototyp von collectionView an die Ansicht eines collectionViewItems binden würde. Ich sage es ist unmöglich, aber ich bin froh, dass ich mich als falsch erwiesen habe. Zweitens, Apples Dokumentation für NSObject copyWithZone: explizit besagt "Sie sollten diese Methode nicht überschreiben." –

+0

Override copyWithZone: ist ziemlich sicher, solange die Superklasse allocWithZone: darin aufgerufen wird. Habe nicht überprüft, ob sie tatsächlich sagen, es nicht zu tun, aber irgendwie denke ich, dass du es mit allocWithZone verwechseln kannst: oder so etwas. – ctpenrose

1

1) die NSView Unterklasse, die für die Darstellung auf ein Element in der Sammlung Ansicht

2) In dieser Unterklasse verwendet wird, fügen einen Delegierten Eigenschaft

3) Sublcass die NSCollectionViewItem

4) Aufschalten die Methode setView: Fügen Sie eine Zeile hinzu, um die Delegate-Eigenschaft der Ansicht auf die NSCollectionViewItem-Instanz (d. H. Self) festzulegen.

Jetzt haben Sie innerhalb der NSView-Unterklasse Zugriff auf das entsprechende NSCollectionView-Element über die delegate-Eigenschaft (z. B. können Sie auf das representierteObjekt zugreifen).

+0

Die setView-Methode wird veraltet sein (es wird in Apples Dokumentation auf 10.5 und 10.6 angewendet). Obwohl sie in 10.7 aufgerufen wird, wird nicht angegeben, wie lange dies weitergeht. – rougeExciter

0

Ich hatte das gleiche Problem, aber fand eine sehr einfache Lösung: Ich legte die Ansicht in eine andere .xib und verknüpfte dies in der NSCollectionViewItem (die eigentlich ein NSViewController ist). Dann wird die .xib für jede Zelle deserialisiert und alle Ausgänge werden gesetzt.

0
  1. Unterklasse NSView.
  2. Hinzufügen einer Delegiertenmethode zu dieser Unterklasse ... etwas wie - (void)mouseDownOnItemAtIndex:(NSUInteger)index, um dem Listener mitzuteilen, dass der Benutzer auf ein Element in einem bestimmten Index geklickt hat.
  3. Ziehen Sie die Sammlungsansicht, indem Sie self.superview in derselben Klasse verwenden. Erstellen Sie eine Variable zum Speichern eines NSUIntegers. Speichern Sie den Index des Elements mit der Methode [[collectionView subviews] indexOfObject:self]. Übergeben Sie diesen Index in der Delegate-Methode index Parameter.
  4. Die Klasse, die dem Protokoll entspricht, das in Ihrem NSView definiert ist, kann jetzt von jedem Mousedown-Ereignis in einer bestimmten Zelle hören. Wenn Sie das reprotectedObject eines bestimmten Elements wünschen, rufen Sie einfach collectionView:itemAtIndex an und rufen Sie das Objekt ab, indem Sie über die representedObject-Eigenschaft auf NSCollectionViewItem darauf zugreifen.