2016-09-20 2 views
0

Ich habe eine App, die eine Menge Daten nach Gruppe präsentieren muss. Ich hatte in der Eckansicht der Tabelle ein Gruppenauswahlmenü platziert, damit der Benutzer die anzuzeigende Gruppe auswählen konnte.Kakao nstableview dynamische Bindung - ohne IB

Die Spalten dieser Tabelle haben die IDs fld # 0..n und einen zugeordneten Controller zum Abrufen von Daten. In der Zielklasse würde es - unter Verwendung einer IBOutlet-Bindung an den Ansichtscontroller die Gruppenauswahl abrufen und diese verwenden, um über den Schalter auszuwählen, welcher Wert angezeigt werden soll.

Alles war gut, bis ich mehrere View/Fenster Instanzen unterstützen musste. Also dachte ich mir, ich würde zur Laufzeit das ändern? in den Tabellenspalten und deren Bindungen. Bisher habe ich das nur über IB gemacht, also ist dies mein erster Ausflug in die Innereien und stecken geblieben.

Mein Eckansicht Aktionsmenü (was für Benutzer rufen):

- (NSMenu *)menuForEvent:(NSEvent *)event 
{ 
    NSMenu * menu = [[[NSMenu alloc] init] autorelease]; 
    SEL action = @selector(cornerAction:); 
    NSMenuItem * item = nil; 
    int type = 0; 

    // We auto enable items as views present them 
    [menu setAutoenablesItems:YES]; 

    // TableView level column customizations 
    for (NSString * title in titles) 
    { 
     BOOL state = dataView.data == type; 

     item = [[NSMenuItem alloc] initWithTitle:title 
              action:action 
            keyEquivalent:@""]; 
     [item setRepresentedObject:dataView]; 
     [item setState:state]; 
     [item setEnabled:YES]; 
     [item setTag:type++]; 
     [item setTarget:dataView]; 
     [item setAction:action]; 
     [menu addItem:item]; 
     [item release]; 
    } 
    return menu; 
} 

und dann beaufschlagten - aber nicht, wie ich brauche, um herauszufinden, wie die Bindungen aktualisieren:

- (IBAction)cornerAction:(id)sender 
{ 
    // Configure which type of data to show, then columns' identifier and sort 
    self.data = (self == sender ? 0 : [sender tag]); 

    [super cornerAction:sender]; 

    for (NSUInteger itm=0; itm<self.fieldCount; itm++) 
    { 
     NSString * fld = [NSString stringWithFormat:@"fld%@%d", titles[data], itm]; 
     NSString * key = [NSString stringWithFormat:@"srt%@%d", titles[data], itm]; 
     NSSortDescriptor * srt = [NSSortDescriptor sortDescriptorWithKey:key ascending:YES]; 

     [cols[itm] setIdentifier:fld]; 
     [cols[itm] setSortDescriptorPrototype:srt]; 

     [cols[itm] bind:<#(nonnull NSString *)#> 
       toObject:<#(nonnull id)#> 
      withKeyPath:<#(nonnull NSString *)#> 
       options:<#(nullable NSDictionary<NSString *,id> *)#>] 
    } 

    [self reloadArray:YES]; 
} 

cols [ ] ist ein Array von Tabellenspalten, so dass die letzte Zeile ein Ausgangspunkt für das Aktualisieren der Bindungen für die Spalte zum Controller (ein Baumcontroller) zu den richtigen Daten ist. Ich hatte die Klasse aktualisiert, um die Felder fld # placesholder zu entfernen und alle Varianten der fld # und srt # ivars erstellt; Diese geben im Grunde den zugrunde liegenden Ivar zurück. Schließlich ist jeder Zugriff nur lesbar.

Ich dachte, alles, was ich jetzt tun muss, ist Update der Bindung. Ich denke auch, dass die Spalte Änderungen an Bezeichner und Sortierdeskriptor nicht notwendig sind?

Wie auch immer, ich versuche, Plan-B zu vermeiden, der auf Registerkarten zurückgreifen und die Tabellenansicht pro Gruppe instanziieren soll - yuck, oder vielleicht gibt es einen besseren Weg überhaupt?

UPDATE: vorausgesetzt, ich entlang Plan-A fortsetzen sollte nicht diese Arbeit: presume Spaltenbezeichner für cols [0]

 [cols[itm] bind: @"value" 
       toObject: treeController 
      withKeyPath: [NSString stringWithFormat:@"arrangedObjects.%@",fld] 
       options: nil] 
+0

Basiert die Tabellenansicht auf einer Zelle oder auf einer Zelle? – Willeke

+1

Wenn Sie eine Tabelle an einen Controller gebunden haben und Sie möchten ändern, was in der Tabelle angezeigt wird, ändern Sie normalerweise den Inhalt des Controllers ... Sie werden die Bindungen der Ansicht nicht abreißen. Wenn Sie möchten, dass ein anderer Datensatz verknüpft und anders angezeigt wird, möchten Sie ihn möglicherweise ansprechen, indem Sie eine andere Ansicht dynamisch anzeigen, nicht dieselbe Ansicht mit rekonstruierten Bindungen. – stevesliva

+0

Also, ja, es ist ein bisschen die Eier in ein Omelett zu scramblen, also benutze eine Tab-Ansicht (tab less) von mehreren Tabs, die ich denke, ist der Weg zu gehen. – slashlos

Antwort

0

Aufgrund impliziten Caching fld0 ist/Objekt die einfachste Lösung war das Klonen der instanziiert Tabellenansicht. Die Benutzeroberfläche wurde konsistent gehalten, so dass für den Benutzer keine sichtbaren Änderungen erforderlich waren. Dies ist ein Modell für andere ähnliche Anforderungen - wie große Datenmengen über eine Metapher mit einem einzelnen Objektiv/Tabellenansicht angezeigt werden können.

Verwandte Themen