Groupe d'objets

Bonsoir à  tous,

j'ai fait une recherche sans grand résultat pour savoir s'il était possible de griser des boutons (contenus dans un groupe) après avoir cliqué sur l'un d'eux; Je vous traduit ça en langage simple :


//déclarations des boutons
bouton1;
bouton2;
bouton3;
bouton4;

//déclaration du groupe boutons
groupeBoutons = tous les boutons

//code
if (appuiBouton1,2,3 ou 4 = yes) alors {

    bouton1.grisé;
    bouton2.grisé;
    bouton3.grisé;
    bouton4.grisé;
}

ou

plus précisément j'aimerai avoir :

//code
if (appuiBouton1,2,3 ou 4 = yes) alors {

    groupeBoutons.grisé;

}

j'espère que c'est plus compréhensible de cette manière. Si ce n'est pas possible je ferai bouton par bouton mais vu qu'il y en aura beaucoup j'aimerai une fonction groupée.

Merci pour votre aide

neospirit

Réponses

  • mpergandmpergand Membre
    23:19 modifié #2
    Une solution, c'est de sous classer NSBox:
    <br /><br />@interface&nbsp; GroupBox : NSBox	{<br /><br />		BOOL isEnabled;<br />}<br /><br />-(void) setEnabled:(BOOL) flag;<br /><br />@end<br /><br />@implementation GroupBox<br /><br />-(void) setEnabled:(BOOL) flag<br />{<br />	int i;<br />	NSArray* v=[[self contentView] subviews];<br />	<br />	for(i=0;i&lt;[v count];i++)<br />		{<br />		id o=[v objectAtIndex:i];<br />		<br />		if( [o isKindOfClass: [NSControl class]] )<br />			{<br />			[o setEnabled:flag];<br />			}<br />		}<br />}<br /><br /><br />@end<br /><br />
    


    Déjà  discuté sur ce forum, il y a quelques années  ...
  • neospiritneospirit Membre
    23:19 modifié #3
    dans 1290213453:

    Une solution, c'est de sous classer NSBox:


    Merci pour l'info mpergand mais je ne comprends pas vraiment ce que tu as écrit en code. Je comprends le fait de sous-classer NSBox (et encore...) mais je vois pas trop le rapport avec mes boutons que je veux cacher en cliquant sur l'un d'entre eux.

    Pourrais-tu détailler svp ?

    Merci

    neospirit
  • laudemalaudema Membre
    23:19 modifié #4
    Sans (plus) vouloir répondre à  sa place cette méthode est assez "self explanatory". Tu l'appelles sur ta boxView dans l'action de tes bouton et elle inspecte toutes ses vues en mettant flag pour valeur de enabled .
    Tu n'as qu'à  regarder les méthodes
    subviews de NSView http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html#//apple_ref/doc/uid/20000014-BBCDFGAG

    setEnabled de NSControl http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/doc/uid/20000073-setEnabled_

    Et isKindOfClass de NSObject Protocol http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/doc/uid/20000052-BBCBFBDJ
  • mpergandmpergand Membre
    23:19 modifié #5
    Si tu regroupes tous tes boutons dans un GroupBox, tu peux les griser en une seule opération.

    Maintenant tu parles de les cacher, ce n'est pas la même méthode, c'est setHidden: et ça peut s'appliquer aussi au NSViews.

    Sinon, pour traiter des groupes d'objets, on peut utiliser les tags.
    groupe1 -> tags 100, 101, 102, ...
    groupe2 -> tags 200, 201, 202, ...

    On récupère l'objet avec la méthode viewWithTag:
    et on fait le traitement dans une boucle.
  • neospiritneospirit Membre
    23:19 modifié #6
    Pour aller plus loin je vais expliquer complètement le concept de ce que je veux faire.

    Imaginons 3 boutons (1 sur différentes vues). En fait j'en aurais plus d'une quinzaine, j'aimerais donc minimiser le code au maximum.
    Quand je clique sur l'un de ces 3 boutons, les 3 boutons devront se griser et en fonction du bouton cliqué, j'incrémente une variable attachée à  un bouton. (ex : si j'appuie sur bouton1, j'incrémente variable1. Si j'appuie sur bouton2, j'incrémente variable2, etc)

    Derrière ça, je voudrais savoir si c'est possible de faire une IBAction générique, c'est-à -dire identifier sur quel bouton j'ai appuyé sans avoir une IBAction par bouton. Car ensuite chaque bouton fait les mêmes actions sauf 1 actions propre à  chaque bouton, à  savoir incrémenter la variable attachée au bouton.

    Est-il possible de faire cela :

    Fichier .h
    @interface BoutonViewController : UIViewController {

    IBOutlet UIButton *bouton1;
    IBOutlet UIButton *bouton2;
    IBOutlet UIButton *bouton3;

    @property (nonatomic, retain) IBOutlet UIButton *bouton1;
    @property (nonatomic, retain) IBOutlet UIButton *bouton2;
    @property (nonatomic, retain) IBOutlet UIButton *bouton3;
    }

    - (void) incVariableBoutonX:(IBOutlet UIButton *) boutonX;


    Fichier .m

    //fonction appelant plusieurs fonctions après appui d'un bouton
    - (void) incVariableBoutonX:(IBOutlet UIButton *) boutonX {

        [self griserBoutons];
        [self incVariableX];

    }


    Merci pour votre réponse

    neospirit
  • laudemalaudema Membre
    23:19 modifié #7
    Peut être pourrais tu utiliser une NSMatrix ? Si tu peux aligner tes boutons "au carré" dans ton interface.
    Une NSMatrix permet d'avoir une action quand on clique dessus ou sur n'importe laquelle de ses cellules, elle permet aussi tout un tas de configurations qui semblent correspondre à  tes besoins
    Référence: http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSMatrix_Class/Reference/Reference.html#//apple_ref/doc/uid/20000106-SW18
    Programming Guide: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Matrix/Matrix.html%23//apple_ref/doc/uid/10000022-CJBEGHBI

    Pour la créer dans Interface Builder tu crées d'abord tes boutons, tu les sélectionnes tous, puis dans le menu "Layout" -> "Embed Objects In" -> "Matrix"
  • neospiritneospirit Membre
    23:19 modifié #8
    Je pense que je ne peux pas utiliser NSMatrix car mes boutons auront les mêmes coordonnées dans chaque vue (ou page). Je ne peux donc pas les mettre "au carré".  :o
  • neospiritneospirit Membre
    23:19 modifié #9
    Ca y est !! Après 3h de bidouille et d'essais, j'ai enfin réussi à  faire ce que je voulais. Et c'était pas si dur. Je me rends compte qu'en utilisant les bases on y arrive 10 fois mieux qu'en essayant de se compliquer la vie.

    J'ai créé cette méthode :

    -(IBAction) incrementeVariable:(UIButton *) button {<br /><br />	int tagBouton = [button tag];<br />	int variable1;<br />	int variable2;<br />	switch (tagBouton) {<br />		<br />		case 122:<br />			variable1++;<br />			break;<br />		case 74:<br />			variable1++;<br />			break;<br />		default:<br />			break;<br />	}<br />	<br />}<br />
    


    J'ai ensuite lié les boutons à  "Actions received" du File's owner dans Interface builder et voilà  ! Je suis presque satisfait.

    Parce que maintenant j'ai un autre problème. Le bouton sur lequel je clique ne veut plus se cacher avec
    bouton.hidden=YES;
    

    car je suppose qu'il est utilisé par l'application. Y a t il un moyen de le libérer pour le cacher ? Sachant qu'au final je vais griser et non cacher les boutons finalement...  :D

    Merci pour vos suggestions

    neospirit
  • AliGatorAliGator Membre, Modérateur
    novembre 2010 modifié #10
    Pour incrémenter la bonne variable en fonction du bouton cliqué, avoir autant de variables que de boutons n'est pas la meilleure solution. Il est plus adapté d'avoir un tableau de 20 "int" que d'avoir 20 variables chacune de type "int", car avec un tableau tu vas pouvoir accéder à  une variable avec un index, index correspondant au numéro du bouton bien sûr dans notre cas.

    Car là  tu vois bien que tu restes pas le plus efficace avec ta solution vu que tu es obligé de mettre un switch/case avec autant de "case" que tu auras de bouton... et alors que le code dans chaque "case" est très similaire !
    Alors qu'avec un tableau (de type C, pas un NSArray, on pourrait mais pour un tableau de largeur fixe, contenant juste des entiers qui plus est, autant prendre un bête tableau C) tu peux utiliser le tag du bouton aussi pour indexer ton tableau.
    -(IBAction)clicBoutonGenerique:(NSButton*)sender {<br />&nbsp; // ... ici tu mets code générique commun à  tous les boutons<br />&nbsp; ... <br />&nbsp; // et ici on veut incrémenter la variable X<br />&nbsp; NSInteger indexBtn = [sender tag]; // on récupère le tag qui va nous donner un index correspondant au bouton cliqué<br />&nbsp; variables[indexBtn]++;<br />}
    
    Bien sûr pour que cela marche, il faut que tu donnes un tag différent à  chacun de tes boutons dans InterfaceBuilder, que tu inscrives la valeur 1 dans la case "tag" de la palette de propriété pour le premier bouton, la valeur 2 pour le 2e bouton, etc.




    PS : dans ton exemple plus haut tu parles de "UIButton", pourtant le sujet est dans le forum "MacOSX" et pas "iOS"... du coup c'est quoi c'est ton exemple qui est mauvais ou c'est que tu n'as pas mis dans la bonne section ? Tu veux pour mac ou pour iOS ? Ceci dit de toutes façon là  vu la question c'est pas plutôt une question qui marche pour les deux, et donc que tu aurais dû mettre dans la section commune ? (Merci de bien mettre vos questions dans la bonne question, y'a pas un seul jour sur le forum où y'a pas un message posté au mauvais endroit c'est lassant et bcp de boulot de tout reventiller... quand on a le temps...)
  • neospiritneospirit Membre
    novembre 2010 modifié #11
    En effet je me suis trompé de topic. Je voulais mettre cette conversation dans iOS. Sorry...

    Pour le reste, ce que tu me conseilles est effectivement une meilleur méthode que la mienne. J'ai essayé sauf que l'application crashe alors que j'ai fait comme tu dis.

    Par contre, as-tu une idée pour les boutons qui ne se cachent pas ?


    Merci
    neospirit
  • neospiritneospirit Membre
    23:19 modifié #12
    Voici mon code après le crash de l'application :


    <br />-(IBAction) cliqueBouton:(UIButton *) sender {<br /><br /><br />	//Les valeur des index du tableau seront ensuite stockées dans un fichier PLIST<br />	int tableauIncVar[5];<br />	tableauIncVar[0]=23;<br />	tableauIncVar[1]=56;<br />	tableauIncVar[2]=75;<br />	tableauIncVar[3]=14;<br />	tableauIncVar[4]=42;<br />	<br />	NSInteger indexBtn = [sender tag];<br />	tableauIncVar[indexBtn]++;<br />	<br />}
    


    Pour l'instant, je ne vois pas où initialiser mes index de tableau à  part dans la fonction elle même...
  • AliGatorAliGator Membre, Modérateur
    23:19 modifié #13
    Que renvoie indexBtn ? Testes-le avant de l'utiliser comme index de tableauIncVar, il suffit qu'il vaille, pour une raison ou une autre une valeur supérieure à  4 (tag associé au bouton mal rentré tu as tapé 10 au lieu de 1 par exemple... ou a mis des valeurs de 1 à  5 au lieu de 0 à  4 pour tes tags...) et ça expliquerait le crash

    Pour initialiser ton tableau, le meilleur endroit c'est dans les méthodes d'initialisation, comme "viewDidLoad" si c'est un ViewController, ou les variantes de "init" (initWithCoder si ta classe est désarchivé d'un XIB, initWithFrame si c'est une UIView, initWithNibName:bundle si c'est un ViewController, init tout court si c'est un NSObject, ...)...
    Ou alors dans le applicationDidFinishLaunchingWithOptions de ton AppDelegate si tes variables ont un scope appwide, ça dépend où tu comptes mettre ton ivar tableauIncVar finalement.
  • neospiritneospirit Membre
    23:19 modifié #14
    dans 1290550497:

    Que renvoie indexBtn ?

    Il renvoie le tag du bouton. Et j'ai trouvé pourquoi ça crashait. J'avais oublié de supprimer une liaison d'un bouton vers une IBAction qui n'existait plus.

    Quand tu parles de tester "indexBtn", veux tu dire juste avec un simple if (0 < indexBtn < x), x étant ma valeur de tag de bouton max ?

    Ensuite pour les valeurs du tableau, elles seront égales à  des valeurs qui seront stockées dans un .plist. J'ai juste initialisé un tableau pour tester ma fonction cliqueBouton.

Connectez-vous ou Inscrivez-vous pour répondre.