2010-10-20 5 views
13

Je suis nouveau sur le Mac. J'essaye de mettre à jour une cellule particulière dans NSTableView sans employer -reloadData, pendant que -reloadData met à jour la table entière. J'ai tout essayé mais tout était en vain. J'essaye de faire quelque chose semblable à ce que nous avions l'habitude de faire dans CListCtrl dans MFC ou dans .NET.Comment mettre à jour NSTableView sans utiliser -reloadData?

+1

Permettez-moi de clarifier un peu plus, je ne Je ne veux pas que la table soit redessinée. Je veux une méthode dans laquelle je peux passer le row_number, column_number ou NSTableColumn, et le (id) dataobject. – Omayr

+10

@Mike Abdullah J'aurais apprécié si vous aviez proposé une solution à la place! – Omayr

+3

Lorsque vous rejoignez une communauté, c'est généralement une bonne idée de prendre note et d'adopter les conventions de cette communauté. Dans le cas de la communauté des développeurs Mac, dire "MAC" tend à indiquer l'ignorance de la plate-forme. –

Répondre

27

Regardez la méthode reloadDataForRowIndexes:columnIndexes:. Pour mettre à jour une seule cellule suivante doit fonctionner:

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

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

+0

Bien que ce soit la solution correcte, il convient de mentionner que reloadData() ne fait que restituer les cellules visibles et non la totalité de la table. – Matt

-3

En général, la mise à jour toute la table via reloadData: est le modèle de conception correcte. Pourquoi êtes-vous opposé à le faire? Est-ce pour des raisons d'efficacité, ou comptez-vous sur la table pour sauver un état et recharger toutes les données interfère avec cela? Ce dernier est généralement un signe que vous devez repenser votre architecture.

+2

Je veux le faire en raison de l'efficacité.Comme j'ai besoin de mettre à jour 8-10 cellules par seconde, dans ce cas, je ne veux pas que toute la table soit mise à jour encore et encore! – Omayr

18

Il s'agit d'une différence fondamentale entre la façon dont les vues fonctionnent généralement dans Cocoa et leur fonctionnement dans d'autres frameworks. NSTableView expose une API -reloadDataForRowIndexes:columnIndexes:, comme le souligne Vladimir, mais vous remarquerez l'absence d'un paramètre "withObject:". Ceci est dû au fait que les vues et contrôles Cocoa sont et non conçus pour servir également de conteneurs de données. Ils sont plutôt destinés à la présentation et à l'interaction avec des données gérées par un autre objet modèle, généralement via un contrôleur intermédiaire quelconque. Dans une vue de table, par exemple, si votre modèle a informé votre contrôleur que certaines données particulières ont changé, le contrôleur peut invalider la partie affichée de la table qui correspond à cette valeur - s'il y a portion de la table. La prochaine fois qu'il se dessine, la table demandera à sa source de données (le contrôleur) pour les valeurs à présenter pour la zone dont elle a besoin pour redessiner.

Ainsi, malgré une similitude superficielle dans l'interaction de l'utilisateur, vous voudrez probablement reconsidérer la façon dont vous écrivez le code pour implémenter votre interface utilisateur. Vous finirez avec beaucoup plus de code de style Model-View-Controller factorisé à la fin; le prix à payer est que vous devrez représenter votre modèle de façon plus approfondie que vous n'auriez pu le faire dans des cadres qui n'exigeaient pas une telle séparation des préoccupations.

1

Un exemple complet de l'utilisation reloadDataForRowIndexes de mettre à jour toutes les lignes, mais seulement une seule colonne:

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

Ou toutes les colonnes pour une seule ligne:

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

Dans votre deuxième exemple, 'reloadDataForRowIndexes: columnIndexes:' ne peut pas prendre de NSRange, vous devez donc faire quelque chose comme: '[NSIndexSet indexSetWithIndexesInRange: NSMakeRange (0, _tableView.numberOfColumns)]' – TheNextman

Questions connexes