web-dev-qa-db-fra.com

Comment définir l'état UIButton pour qu'il soit mis en surbrillance après avoir appuyé dessus

J'ai une exigence typique dans laquelle je dois garder un bouton en surbrillance après l'avoir appuyé. Je dois effectuer une tâche qui ne devrait fonctionner que lorsqu'un bouton est en surbrillance. En fait, je mets en surbrillance par programmation un état du bouton. 

[sender setHighlighted:YES]; 

Et une fois le bouton en surbrillance, je dois effectuer une autre action. 

- (IBAction)changeState: (UIButton*)sender
{   
    if (sender.highlighted == YES)
    {
        [self performSomeAtion:sender];
    }
}

Mais, à mon horreur, chaque fois que j'appuie sur un bouton, la condition ci-dessus devient vraie et l'action est exécutée à plusieurs reprises. Existe-t-il un moyen de conserver l'état de UIButton après l'avoir appuyé?

EDIT- En fait, je dois effectuer 3 actions différentes pour 3 états différents du bouton. Je me sers déjà de l'état sélectionné et de l'état normal. Maintenant, je dois utiliser l'état mis en évidence.

14
A for Alpha
[sender setSelected:YES]; 

ou vous pouvez simuler cet effet avec deux images pour votre UIButton (notselectedimage.png et selectedimage.png), puis conservez l'état du bouton de suivi avec une variable BOOL telle que BOOL buttonCurrentStatus;. Puis dans le fichier .h:

BOOL buttonCurrentStatus;

et dans le fichier .m

// connect this method with Touchupinside function
- (IBAction)changeState:(UIButton*)sender
{
    /* if we have multiple buttons, then we can
       differentiate them by tag value of button.*/
    // But note that you have to set the tag value before use this method.

  if([sender tag] == yourButtontag){

    if (buttonCurrentStatus == NO)
    {
        buttonCurrentStatus = YES;
        [butt setImage: [UIImage imageNamed:@"selectedImage.png"] forState:UIControlStateNormal];
        //[self performSomeAction:sender];
    }
    else
    {
        buttonCurrentStatus = NO;
        [butt setImage:[UIImage imageNamed:@"notSelectedImage.png"] forState:UIControlStateNormal];
        //[self performSomeAction:sender];
    }   
  }
}
- (void)mybutton:(id)sender
{
    UIButton *button = (UIButton *)sender;
    button.selected = ![button isSelected]; // Important line
    if (button.selected)
    {
        NSLog(@"Selected");
        NSLog(@"%i",button.tag);
    }
    else
    {
        NSLog(@"Un Selected");
        NSLog(@"%i",button.tag);

    }
 }
7
svmrajesh

L'état mis en surbrillance est utilisé pour mettre en surbrillance le bouton while il est touché. Un touché dans le bouton le surligne. Vous devez utiliser l'état "sélectionné" à la place. 

Si vous souhaitez exécuter une action après avoir appuyé sur le bouton, ne liez pas votre méthode à l'événement de changement d'état, mais attachez votre méthode à l'événement TouchUpInside.

4
progrmr

Je viens de trouver un moyen, alors je le partage, juste au cas où ...

J'ai gardé mon bouton UIB et réglé une image pour chaque état (vous pouvez donc aller jusqu'à un bouton 4 états) . ce premier bouton est de montrer un état

Je crée un deuxième UIButton personnalisé avec le même cadre que le premier. Pour celui-ci, aucune image ne sera définie pour l'état (c'est un bouton totalement transparent). Le but de ce bouton est d’attraper l’événement tactile. J'ai donc ajouté une cible à ce bouton lors de l'événement TouchUpInside. Et puis, lorsque l'événement est déclenché, je modifie l'état du premier bouton sur Désactivé, Surligné, Sélectionné ou aucun de ces états (= État par défaut).

Tout fonctionne comme un charme!

3
Hal

Comme vous le décrivez, vous feriez mieux de sous-classer UIView pour créer votre propre bouton à trois états. 

En fait, vous devriez même implémenter votre propre buttonView multi-états et gérer l'état dans lequel il se trouve de manière interne via un tableau de PNG pour les apparences et un tableau d'états pour savoir combien de fois il a été appuyé.

2
Kheldar

Utilisez [sender setSelected: YES];, je pense que cela vous sera utile.

1
Narayana

Pour iOS 7 uniquement: vous devez envisager de définir l'image renderMode sur UIImageRenderingModeAlwaysTemplate. Vous pouvez ensuite utiliser le paramètre tintColor pour représenter différents états. 

voir Comment appliquer une teinteColor à une UIImage? et 

voir Teinte un UIView avec toutes ses sous-vues

0
John Henckel

Selon Apple, UIButton a la propriété de imageView :

Bien que cette propriété soit en lecture seule, ses propres propriétés sont en lecture/écriture. Utilisez ces propriétés pour configurer l’apparence et le comportement de la vue du bouton.

Cela signifie que vous pouvez définir une image pour ce bouton dans l'IB (dans le storyboard) et définir l'image en surbrillance:

  1. Ouvrez l'inspecteur d'attributs.
  2. Dans la section Button, choisissez une image.
  3. Dans la même section, modifiez la configuration d'état en surbrillance. Remarquez que l'image que vous avez choisie par défaut est maintenant partie et que vous pouvez maintenant définir une nouvelle image pour la surbrillance.
  4. Maintenant, vous avez un bouton avec la configuration à 2 états et tout ce que vous avez à faire pendant l'exécution pour changer le button.highlighted = true. Consultez également UIControl sous Configuration des attributs du contrôle pour plus d’états.

Vous pouvez également le faire par programme comme suit:

Swift (et presque identique en Objective-C):

// Setting the highlighted image
self.someButton.imageView?.highlightedImage = UIImage(named: "imageNameFromImageAssest")
// someButton will now some the highlighted image and NOT the image set in the IB
self.someButton.imageView?.highlighted = true
0
OhadM
UIButton *btn_tmp=sender;
    if(!(btn_tmp.selected))
    {
[btn_temp setHighlighted:YES];

}
0
Narayana

La solution est délicate mais c'est possible.

Le problème est que vous avez essayé de changer le statut en surbrillance dans la méthode d'action du bouton, ce qui suppose un processus de nettoyage ou de vérification à la fin de l'action et que vous basculez le statut en surbrillance. Lorsque vous essayez de le déboguer, vous obtenez la valeur en surbrillance = 1, mais cela changera à la fin.

Étrange mais votre "bouton 3 statuts" est parfois utile, lorsque vous souhaitez conserver un bouton en mode "surligné" comme le mode "sélectionné" pour obtenir une action différente en fonction des 3 statuts . Le seul problème que vous impossible d'analyser cela ou de passer en mode surligné dans la méthode d'action du bouton, car ce dernier bascule immédiatement en mode en surbrillance lorsque l'utilisateur appuie dessus ET le rétablit à la fin.

La solution utilise une dépêche.

dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [theButton setHighlighted:YES];
});

Cela fera l'affaire et vous pourriez utiliser les 3 statuts.

0
BootMaker