Mise à jour d'un controleur de tableau par code (NSArrayController)
Bonjour,
En ce moment, pour parfaire ma connaissance de Cocoa sur MAC, je m'amuse à écrire un outil pour aider les MJ (maitres de jeu) car s'il y a pléthore de logiciels de ce type sur PC ce n'est pas forcément le cas sous MAC.
Pour commencer tranquille j'ai écrit un petit gestionnaire d'initiative (on prend une liste de "combattants" et on génére un nombre entre 1 et 20 puis on classe le tout).
Ca donne ce que vous voyez dans la copie ci-contre.
Pour ce faire en cocoa on travaille avec 2 objets:
- le tableau (NSTableView)
- un controleur de données (le NSArrayController)
Avec quelques manips rapide et très peu de code (et le chapitre 8 de la programmation cocoa), on arrive rapidement à un résultat mais il manque le tri après le calcul.
Bien sur on peut se contenter de cliquer sur la colonne "initiative calculée" qui fera le travail pour vous mais ça fait un clic de plus qu'un MJ débordé aura du mal à faire :-)
J'ai donc voulu faire le travail en background en faisant le travail par code.
Il suffit d'écrire une fonction de tri façon lambda expression sur C# et ça donne ce genre de choses:
NSArray *sortedArray; NSComparisonResult (^sortBlock)(id, id) = ^(id obj1, id obj2) { Combattant *first = (Combattant*)obj1; Combattant *second = (Combattant*)obj2; if (first.initiative > second.initiative) { return (NSComparisonResult)NSOrderedAscending; } else if (first.initiative < second.initiative) { return (NSComparisonResult)NSOrderedDescending; } return (NSComparisonResult)NSOrderedSame; }; sortedArray = [combattants sortedArrayUsingComparator:sortBlock];
Mais une fois que l'on met à jour le tableau rien ne se passe sur l'écran (alors qu'un NSLog me prouve que ça marche)....
.. quelques recherches plus tard .....
J'ai découvert qu'il fallait prévenir le(s) controleur(s) de ce changement. Cela se fait assez simplement de la manière suivante:
[self willChangeValueForKey:@"combattants"];//on prévient les controleurs du changement à venir [a retain]; [combattants release]; combattants = a; [self didChangeValueForKey:@"combattants"];//on prévient les controleurs que le changement est fait
Au final 2 petites lignes de code très précieuses. L'autre gros avantage de cette méthode est que tous les controlleurs se rattachant au tableau (si vous avez plusieurs fenêtre) pourront se mettre à jour ensemble.
A très bientôt dans l'atelier.