Ich habe erfolgreich eine NSCollectionView erstellt und dem Ansichtsprototyp in IB eine Beschriftung hinzugefügt, die an eine Eigenschaft meines dargestellten Objekts gebunden ist. Ich möchte jetzt ein NSButton und NSTextField mit dem NSTextField programmatisch erstellen, das an eine Eigenschaft meines dargestellten Objekts gebunden ist. Wenn die Schaltfläche geklickt wird, möchte ich das NSTextField ein- und ausblenden.Wie binde ich programmatisch in der Sichtunterklasse meiner NSCollectionView?
Das Problem, das mir begegnet ist, wenn ich meinen Initialisierungscode für meine Steuerelemente in der InitWithCoder -Methode der Ansicht und die Bindung in der Ansicht watchFromNib der Ansicht, die Bindung wird nicht angeschlossen. Wenn ich die Initialisierung für meine Steuerelemente in die watchFromNib-Funktion lege, habe ich beim Klicken auf die Schaltfläche keinen Zugriff auf die Steuerelemente in meiner Ansicht (sie sind null, wenn sie mit NSLog ausgedruckt werden).
Von dem, was ich sagen kann sieht es aus wie das Problem möglicherweise, dass die Art, wie NSCollectionView funktioniert, eine Instanz der Ansicht erstellt und kopiert es dann für wie viele Objekte in der Sammlungsansicht sind. Wie bekomme ich die Schaltflächen zum Initialisieren und die Bindung mit der Kopie des Prototyps zu arbeiten?
Unten ist mein Code für die Initialisierung und meine im awakeFromNib für meine Unterklasse Ansicht Bindung:
SubView.h
@interface SubView : NSView {
NSButton *button;
NSTextField *textField;
IBOutlet NSCollectionViewItem *item; // Connected in IB to my NSCollectionViewItem
}
- (IBAction)buttonClicked:(id)sender;
@end
SubView.m
@implementation SubView
- (id)initWithCoder:(NSCoder *)decoder
{
id view = [super initWithCoder:decoder];
button = [[NSButton alloc] initWithFrame:NSMakeRect(50, 95, 100, 20)];
[button setTitle:@"Begin Editing"];
[button setTarget:self];
[button setAction:@selector(buttonClicked:)];
[self addSubview:button];
textField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 100, 75)];
[self addSubview:textField];
return(view);
}
- (void)awakeFromNib
{
// Bind the textField to the representedObject's name property
[textField bind:@"value"
toObject:item
withKeyPath:@"representedObject.name"
options:nil];
}
- (IBAction)buttonClicked:(id)sender
{
[button setTitle:@"End Editing"];
[textField setHidden:YES];
}
@end
rechts, wenn ich versuche, meine Bindung Code in initWithCoder zu setzen: ich bekomme diese Fehlermeldung: Eine abgefangene Ausnahme 01 angehoben wurdeController kann nicht Null sein *** Beenden App aufgrund der nicht abgefangenen Ausnahme 'NSInvalidArgumentException', Grund: 'Controller kann nicht Null' Ich denke, es ist, weil die "Element" -Eigenschaft (ein IB Outlet zu CollectionViewItem) noch nicht ist verbunden in initWithCoder. Gibt es eine andere Möglichkeit, zum reprodedObject zu gelangen? – Austin
Hmm .. guter Punkt. Wahrscheinlich die beste Problemumgehung wäre, den Bindungscode in eine andere Methode zu schreiben und sie dann mit -performSelector aufzurufen: withObject: afterDelay: 0.0. Es ist nicht schön, aber es sollte funktionieren, da ich denke, dass es keine Alternative gibt. – kperryua
Ich habe versucht, den Bindungscode mit dem performSelector aufzurufen: withObject: afterDelay von meinem initWithCoder, aber das Problem ist, dass der initWithCoder aufgerufen wird, dann wakeFromNib, dann initWithCoder wird für jede Sammlung View-Element aufgerufen. Können Sie Ihre Antwort ändern, um den verbindlichen Code anzuzeigen, der Ihrer Meinung nach funktionieren sollte? – Austin