UIButton et UIImage
Bonjour
J'ai une petite question en rapport avec les images pour les UIButton :
Je souhaite qu'a chaque fois que j'appuie sur un bouton quelconque, l'image de "bouton1" change. J'utilise donc ce morceau de code :
Le problème est que je n'ai pas qu'un mais une dizaine de boutons.
J'aimerai savoir si il est possible de réduire le code de façon à se que je ne marque pas dix fois ce bout de code. Est-ce possible ?
Merci ! /wink.png' class='bbc_emoticon' alt=';)' />
J'ai une petite question en rapport avec les images pour les UIButton :
Je souhaite qu'a chaque fois que j'appuie sur un bouton quelconque, l'image de "bouton1" change. J'utilise donc ce morceau de code :
<br />
UIImage *imageBouton1 = [UIImage imageNamed:@"Image1"];<br />
[bouton1 setImage:imageBouton1 forState:UIControlStateNormal];<br />
Le problème est que je n'ai pas qu'un mais une dizaine de boutons.
J'aimerai savoir si il est possible de réduire le code de façon à se que je ne marque pas dix fois ce bout de code. Est-ce possible ?
Merci ! /wink.png' class='bbc_emoticon' alt=';)' />
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En tout cas c'est une excellente idée de ne pas vouloir multiplier le même bout de code ; Martin Fowler n'a pas travaillé pour rien /implore.gif' class='bbc_emoticon' alt=' ' />
C'est à dire ? Aurais-tu un exemple pour illustrer ?
Merci ! /smile.png' class='bbc_emoticon' alt=':)' />
Combien de contrôleurs ? Est-ce que ces contrôleurs ont des comportements communs ?
Comme je ne suis pas sûr que je donne vraiment la bonne réponse à ta question, je te donne mon projet test. Il y a seulement 2 boutons mais c'est juste pour te montrer comment je code pour changer des images.
Tu réponds en partie à ma question ; tous les boutons sont manipulés par le même contrôleur de vue ; ça facilite les choses.
D'abord, pour seulement 2 boutons, il ne faut pas se casser la tête à factoriser le code ; un bon copier-coller des familles sera tout à fait satisfaisant. À partir de 4-5 je dirais (mais c'est affaire de sensibilité personnelle) il faut siouxer.
On va donc supposer que tu voudras un jour mettre 4 ou 5 boutons voire beaucoup plus.
J'ai alors besoin de savoir encore 2 trucs :
- Je suppose aussi que le contrôleur de vue définit une méthode d'action pour chaque bouton, exact ?
- Est-ce que les méthodes d'action ne font que changer l'image où font elle autre chose aussi ?
Non, mes méthodes d'actions ne font que changer les images à partir d'une valeur bollean. /smile.png' class='bbc_emoticon' alt=':)' />
Il suffit que tous les boutons active la même méthode du contrôleur. Il faut utiliser la version avec le paramètre sender du prototype IBAction.
Ensuite dans la méthode, il faut trouver un système qui permette de récupérer la bonne image en fonction de la valeur du paramètre sender (qui est une référence au bouton qui a été touché).
Il y a plusieurs moyens pour lier une image à un bouton :
ça y est, je suis largué.
Il y avait forcément besoin des tags ? Sinon au lieu d'utiliser les tags je peux aussi utiliser le titre du bouton pour gérer mes actions /smile.png' class='bbc_emoticon' alt=':)' />
Ce que tu peux faire c'est dans le .xib si tu utilise les xib définir une image pour ton bouton en mode normal et l'autre image en mode "selected"
Ensuite tu fais ce code
Tu relis ton action à tous tes button du xib et ça devrait le faire.
Ce que ça va faire c'est faire une sorte de selection c'est a dire que ton bouton aura deux états, un normal avec ton image de départ et un séléctionné avec une autre image.
Si il faut que ça soit seulement au moment où tu cliques que l'image change alors tu peux jouer avec l'highlighted toujours dans ton .xib.
Ceci dis cela marche aussi en code mais c'est juste horrible de doubler tous les codes pour ajouter les images selectionnées.
Dans le fichier .h
Dans le fichier .m
J'ajoute également un capture d'écran pour vous faire une petite idée de l'interface.
Dans la partie encadré en rouge de mon image tu peux changer "default" pour "selected" tu peux mettre des images diffèrente pour les deux cas.
Du coup xcode comprend que le bouton peut changer d'image sur certaine condition. ça marche pour les titre les images les background image et les couleur des textes.
Le bouton affichera l'image défini dans default tant que "button.selected == FALSE". Elle affichera l'image définie dans selected quand "button.selected == TRUE".
Du coup plus besoin de définir des images dans le code les boutons les ont en mémoire dans les xml généré par interface builder.
Ensuite plus besoin non plus de changer les images des bouton il suffit juste de changer leur valeur "selected" d'où lon code de tout a l'heure
Par contre pour une dizaine de bouton ton système ne pourra pas marcher.
Enfin j'ai l'impression que pour l'instant tu essais plus ou moins de faire l'équivalent de l' "input select" de l'html pour deux boutons ton système marche bien pour plus ça va vite devenir ingérable.
Si jamais tu te lance la dedans moi ce que je fais en général c'est une boucle sur les "subview" je regarde si j'ai a faire a un bouton je lui donne une condition pour éviter de bouger mes autres bouton genre tag > 1000 et la j'initialise tous mes boutons a selected = TRUE; puis je change celui qui a été cliqué.
ça prend un peu plus de ligne de code par contre.
[Hors sujet]
BOOL changement;
changement = FALSE;
if(changement == FALSE)
C'est excessivement redondant
if(changement) suffit amplement /wink.png' class='bbc_emoticon' alt=';)' />
[/Hors sujet]
Oui je sais et c'est bien cela qui m'embête ! /wink.png' class='bbc_emoticon' alt=';)' />
Bah justement ta réponse est très bien mais comme tu dis, seulement pour deux boutons. Moi c'est pour dix... /sad.png' class='bbc_emoticon' alt=':(' />
Par contre j'ai pas bien compris l'explication avec la boucle... Sinon l'explication générale est très bien merci ! /smile.png' class='bbc_emoticon' alt=':)' />
Merci beaucoup du conseil ! J'aime bien qu'on me corrige aussi mon code pour qu'il soit plus court ! /smile.png' class='bbc_emoticon' alt=':)' />
Je suis pas sûr d'avoir tout suivi et bien compris le problème, mais si le but est bien ce que j'ai capté, à savoir avoir N bouton sur ta vue, chacun ayant deux "états" (une image différente pour chaque état), avec un seul bouton dans l'état "sélectionné" uniquement à chaque fois, alors c'est très simple et ne nécessite que très peu de code :
- Placer tous les boutons dans IB, et définir par IB leur image pour l'état "normal" et l'image pour l'état "selected"
- Créer un IBOutletCollection NSArray* buttons et relier tous les boutons à cet IBOutletCollection dans IB
- Créer une IBAction "buttonAction:" et relier tous les boutons à cette même action
- Le seul code à écrire pour que le tout fonctionne est alors le suivant : Et voilà !
Non ?
Sinon je plussoie AliGator comme presque tout le temps (faut toujours laisser une once de doute on sait jamais) car soit tu fais une collection d'objet comme il le précise soit tu es obliger de boucler sur tous les éléments de ta view. Cela revient a dire soit tu boucle sur dix boutons rangés dans un tableau propre, soit tu boucle sur un énorme tableau qui contient tes dix bouton parmi tous les éléments. Si tu suis la logique tu comprendras que la solution d'AliGator est bien plus optimisé pour ton cas.
Après la fonction pour changer les images sera de toute façon pas compliquer a mettre en place. Si tu veux vraiment utiliser mon code je te le donne on sait jamais mais bon personnellement j'essaierais de ne plus l'utiliser
Cela fait la même chose que la fonction d'AliGator avec plus de ligne et en étant moins optimisé.
La condition du tag me semble inutile dans le cas où tu n'as qu'une catégorie de bouton a laquelle tu changes la propriété "selected" car les boutons ont par défaut le "selected" égale à FALSE.
Merci à toi Nasatya pour ta réponse très claire mais je préfère celle AliGator parce qu'il utilise les IBOutletCollection et c'est comme tu dis [font=helvetica, arial, sans-serif]méchamment efficace[/font] /wink.png' class='bbc_emoticon' alt=';)' />
J'ai essayé d'adapter mais je ne suis pas vraiment sûr de mon code :
Si tu voulais continuer à utiliser ta solution, ce type de code serait plus efficace (PS en Objective-C on utilise YES et NO et non TRUE et FALSE) :
@Benjo'; : Ton code me semble bon, bien qu'il soit fortement déconseillé d'utiliser des variables globales comme tu le fais avec ta variable "changement". Il est préférable d'utiliser soit une variable d'instance, soit une variable statique interne à la fonction.
Pour le booléen déjà il me semble que les deux écriture sont correcte puis je trouve ça plus claire le vrais/faux que le oui/non et en plus c'est imposé par une coding style de mon entreprise c'est donc devenu une habitude.
Bon ça c'est pour l'honneur du développeur /wink.png' class='bbc_emoticon' alt=';)' />.
Ensuite pour ton code :
La globale effectivement j'en vois pas souvent mais ce que je comprends pas par dessus tout c'est ce que fait ta fonction.
Je m'explique tu commence en disant
- je met une variable a false / no
- je rentre dans ma fonction
- si false/no (d'ailleurs il me semble que tu as une erreur la if (changement) est l'équivalent de if(changement == true/yes) il te faudrait je pense if(!changement) dans ton cas).
- je fais une boucle pour passer tout mes bouton a select = true;
- je passe "changement" a true/yes
- puis je repasse dans ma boucle je fais l'inverse.
Tout cela n'est il pas équivalent a si mon bouton a son "selected" a true/yes je le passe a false/no si il l'a a false/no je le passe a true/yes?
en clair je pense que ta variable "changement" dans ton cas ne sert a rien.
juste test de changer ta fonction pour ça pour voir
Donc ce n'est pas tout à fait équivalent pour le compilateur qui ne verra pas certaines optimisations ou ne détectera pas certains warnings si tu n'utilises pas les bons termes.
Oui concernant le code de Benjo' je suis d'accord avec toi, la variable "changement" pourrait même totalement sauter et le code peut se résumer à ceci puisque dans son cas l'état selected des boutons est normalement toujours consistant et n'est changé que par ce biais :
Il me semble que dans les commentaires précédents, on me disait que "(changement)" était l'équivalent à "false". /huh.gif' class='bbc_emoticon' alt='???' />
Oui tu as raison j'aurais pu enlever ma variable merci du conseil ! /smile.png' class='bbc_emoticon' alt=':)' />
Pour être clair
if (changement)
{
//action si changement est true/yes
}
else
{
//action si changement est false/no
}
si tu veux l'inverse (ce qui peut être pratique des fois
if (!changement)
{
//action si changement est false/no
}
else
{
//action si changement est true/yes
}
excuse moi pour la confusion dans mon précedent post.
Pas de problème ! /smile.png' class='bbc_emoticon' alt=':)' />