2013-08-30 13 views
9

Ho una semplice app che elenca alcuni modelli in un NSTableView.Aggiunta programmatica di colonne (con collegamenti) a un NSTableView basato su visualizzazione?

La tabella è una tabella basata su viste completamente standard con un paio di colonne e viene popolata tramite un binding NSArrayController. Tutto ciò è impostato in Interface Builder e funziona come previsto.

Ora, vorrei aggiungere altre colonne a livello di codice e tenere queste nuove colonne associate a vari keypath nei modelli. E lì, sono bloccato.

Per semplicità, assumere questa configurazione:

  1. Gli oggetti modello sono oggetti semplici con solo una singola proprietà NSString: name
  2. L'AppDelegate ha una proprietà NSArray (models) che contiene un numero di modello le istanze.
  3. Il NSArrayController's content è associato all'array models del delegato dell'applicazione.
  4. Il numero content di NSTableView è associato a arrangedObjects del controller di array.
  5. prima colonna della tabella viene vincolata (in IB) per visualizzare la proprietà name, cioè colonna → cella di tabella vista → testo statico vista tabella cella → valore è destinato a della visualizzazione cella objectValue.name

Questo è, per quanto ne so, semplice e dal libro, e funziona come un fascino.

Ma ... come aggiungere più colonne, quindi?

Per aggiungere una colonna programatically (per mantenere le cose semplici, diciamo solo che questa nuova colonna deve anche solo visualizzare la proprietà name, proprio come la colonna che è già lì), immagino che avrei fatto qualcosa di simile in il delegato applicazione:

NSTableColumn* newColumn = [[NSTableColumn alloc] initWithIdentifier:@"newColumn"]; 

// do binding magic somehow 
// [[newColumn dataCell] bind:NSValueBinding toObject:??? withKeyPath:??? options:nil]; 

[self.table addColumn:newColumn]; // the table's connected with an IBOutlet 

ho provato tante combinazioni di legame da/alla cella di dati, la tabella, la colonna, il controller di array, la matrice stessa, così come tutti i tipi di keypaths, ma niente funziona. La nuova colonna è stata aggiunta correttamente, ma non è mai stata compilata.

Immagino che l'istanza di base di NSTableColumn che creo sia basata su celle, non basata sulla vista, e ciò sta causando problemi. Tuttavia, non ho idea di come procedere da qui, e i documenti non parlano mai di colonne vincolanti che sono state aggiunte programmaticamente.

In questo caso, tutto ciò che voglio è una semplice colonna di testo, legata al modello, esattamente come quella che posso facilmente configurare IB.

Potrei fare tutto questo implementando un NSTableViewDataSource e "manualmente" alimentando la tabella, ma ho già impostato tutto il resto con i binding.

Qualsiasi aiuto sarebbe molto apprezzato.

risposta

4

Prova in questo modo: -

NSString *akey = @"keyValue"; 
NSString *keypath = [NSString stringWithFormat:@"arrangedObjects.%@",akey]; 
NSTableColumn *tableColumn=[[NSTableColumn alloc]initWithIdentifier:@"newColumn"]; 

[tableView addTableColumn:tableColumn]; 
[tableColumn bind:NSValueBinding toObject:yourArrayController withKeyPath:keypath options:nil]; 
NSMutableDictionary *dc=[NSMutableDictionary dictionary]; 
[dc setObject:@"textValue" forKey:@"keyValue"]; 
[yourmutableArray addObject:dc]; 
[self setYourmutableArray:yourmutableArray]; 

Si prega di notare: - l'array mutevole dovrebbe legarsi a arraycontroller allora solo si popolerà i dati

+0

Siamo spiacenti, non funziona; provato. Il binding della colonna funziona solo per le tabelle basate su celle. Non tabelle basate su viste. – Flambino

2

È necessario legarsi alle subviews di NSTableCellView della colonna che utilizzano questo metodo delegato:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 
{ 
    // Get cell view - NSTableCellView 
    // This can be a prototype loaded from the table view or from another nib 
    // see : - registerNib:forIdentifier: 
    NSView *cellView = [tableView makeViewWithIdentifier:@"Cell1" owner:[tableView delegate]]; 

    // - subViewWithIdentifier is a simple category method that searches -subviews 
    NSView *subView = [cellView subViewWithIdentifier:@"TextField1"]; 
    [subView bind: NSValueBinding toObject:cellView withKeyPath: @"objectValue.name" options: nil]; 

    subView = [cellView subViewWithIdentifier:@"TextField2"]; 
    [subView bind: NSValueBinding toObject:cellView withKeyPath: @"objectValue.address" options: nil]; 

    return cellView; 
} 

NSView metodo categoria:

- (NSView *)subViewWithIdentifier:(NSString *)theIdentifier 
{ 
    __block NSView *subView = nil; 
    [[self subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
#pragma unused(idx) 
     if ([[obj identifier] isEqualToString:theIdentifier]) { 
      subView = obj; 
      *stop = YES; 
     } 
    }]; 
    return subView; 
}