2010-10-20 2 views
13

Sono nuovo al Mac. Sto cercando di aggiornare una cella particolare in NSTableView senza utilizzare -reloadData, come -reloadData aggiorna l'intera tabella. Ho provato tutto ma tutto era invano. Sto cercando di fare qualcosa di simile a quello che facevamo in CListCtrl in MFC o in .NET.Come aggiornare NSTableView senza usare -reloadData?

+1

Lasciatemi chiarire un po 'più, don Voglio che il tavolo sia ridisegnato. Voglio un metodo in cui posso passare il row_number, column_number o NSTableColumn e il (id) dataobject. – Omayr

+10

@Mike Abdullah Mi sarebbe piaciuto se tu avessi proposto una soluzione! – Omayr

+3

Quando si entra in una comunità, di solito è una buona idea prendere atto e adottare le convenzioni di quella comunità. Nel caso della comunità di sviluppatori Mac, il termine "MAC" tende a indicare l'ignoranza della piattaforma. –

risposta

27

Dai un'occhiata al metodo reloadDataForRowIndexes:columnIndexes:. Per aggiornare una singola cella la seguente dovrebbe funzionare:

[yourTable reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:row] 
        columnIndexes:[NSIndexSet indexSetWithIndex:column]]; 
+0

Link Documenti: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTableView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTableView/reloadDataForRowIndexes:columnIndexes: –

+0

Sebbene questa sia la soluzione corretta, è necessario ricordare che reloadData() esegue nuovamente anche il rendering delle celle attualmente visibili e non dell'intera tabella. – Matt

-3

Solitamente, aggiornando l'intera tabella tramite reloadData: è il modello di progettazione corretta. Perché sei contrario a farlo? È per motivi di efficienza, o stai facendo affidamento sul tavolo per salvare qualche stato e ricaricare tutti i dati che interferiscono con quello? Quest'ultimo è di solito un segno che è necessario ripensare la tua architettura.

+2

Voglio farlo a causa dell'efficienza.Come ho bisogno di aggiornare 8-10 celle al secondo in questo caso non voglio che l'intera tabella sia aggiornata più e più volte! – Omayr

18

Questa è una differenza fondamentale tra il modo in cui le visualizzazioni funzionano in genere in Cocoa e il modo in cui funzionano in altri framework. NSTableView espone un'API -reloadDataForRowIndexes:columnIndexes:, come sottolinea Vladimir, ma noterai l'assenza di un parametro "withObject:".

Questo perché le visualizzazioni e i controlli Cocoa sono non progettati per funzionare anche come contenitori di dati. Piuttosto, sono per la presentazione e l'interazione con i dati gestiti da qualche altro oggetto modello, di solito attraverso un controller intermedio di qualche tipo.

Data una visualizzazione per tabella, per esempio, se il modello ha informato il controller che alcuni dati particolari è cambiato, il controller può invalidare la porzione visualizzata del tabella che associa a quel valore - se c'è anche è un visualizzato porzione del tavolo. La prossima volta che si disegna, la tabella chiederà alla sua origine dati (il controller) i valori da presentare per l'area che deve essere ridisegnata.

Quindi, nonostante una somiglianza superficiale nell'interazione dell'utente, probabilmente vorrai riconsiderare come scrivi il codice per implementare la tua interfaccia utente. Alla fine si finirà con un codice stile Model-View-Controller molto più fattorizzato; il prezzo è che dovrai effettivamente rappresentare il tuo modello in modo più approfondito di quanto potresti aver avuto in strutture che non richiedevano una tale separazione di preoccupazioni.

1

Un esempio completo di utilizzo reloadDataForRowIndexes per aggiornare tutte le righe ma solo una singola colonna:

int col = 2 ; 
[self.myTable reloadDataForRowIndexes: 
    [NSIndexSet indexSetWithIndexesInRange: 
     NSMakeRange(0,self.myTable.numberOfRows)] 
    columnIndexes: 
     [NSIndexSet indexSetWithIndex:col] 
]; 

o tutte le colonne per una singola riga:

int row = 2 ; 
[self.myTable reloadDataForRowIndexes: 
    [NSIndexSet indexSetWithIndex:row] 
columnIndexes: 
    [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.myTable.numberOfColumns)] 
]; 
+0

Nel tuo secondo esempio, 'reloadDataForRowIndexes: columnIndexes:' non può prendere un NSRange, quindi è necessario fare qualcosa del tipo: '[NSIndexSet indexSetWithIndexesInRange: NSMakeRange (0, _tableView.numberOfColumns)]' – TheNextman