Canalblog Tous les blogs Top blogs Technologie & Science Tous les blogs Technologie & Science
Editer l'article Suivre ce blog Administration + Créer mon blog
MENU
Atelier code
Publicité
13 avril 2012

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).

Capture d’écran 2012-04-13 à 15Ca 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.

 

Publicité
Commentaires
Atelier code
  • Développeur dotnet dans ma vie quotidienne je suis un touche à tout : iPhone, Raspberry, robotique, développement de jeux vidéos, design. J’ai décidé de partager mes aventures dans le code avec vous et j'espère que vous y prendrez autant plaisir que moi.
  • Accueil du blog
  • Créer un blog avec CanalBlog
Publicité
Archives
Publicité
Publicité