web-dev-qa-db-fra.com

Comment empêcher UIButton de clignoter lors de la mise à jour du titre

Lorsque j'appelle setTitle sur un UIButton, le bouton clignote sous iOS 7. J'ai essayé de définir myButton.highlighted = NO, mais cela n'a pas empêché le bouton de clignoter.

[myButton setTitle:[[NSUserDefaults standardUserDefaults] stringForKey:@"elapsedLabelKey"] forState:UIControlStateNormal];

myButton.highlighted = NO;

Voici comment j'ai configuré le minuteur qui a mis à jour les titres:

- (void)actionTimer {
    if (myTimer == nil) {

        myTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0
                        target: self
                        selector: @selector(showActivity)
                        userInfo: nil
                        repeats: YES];
    }
}

Voici la méthode qui met à jour les titres:

- (void)showActivity {

    NSString *sym = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];

    if (pauseInterval == nil) {

        // Update clock
        seconds = [[NSDate date] timeIntervalSinceDate:startInterval] - breakTime;

        // Update total earned
        secRate = rate.value / 60 / 60;
        total = secRate * seconds;
        [totalLabel setTitle:[NSString stringWithFormat:@"%@%.4f",sym,total] forState:UIControlStateNormal];

        days = seconds / (60 * 60 * 24);
        seconds -= days * (60 * 60 * 24);
        int hours = seconds / (60 * 60);
        fhours = (float)seconds / (60.0 * 60.0);
        seconds -= hours * (60 * 60);
        int minutes = seconds / 60;
        seconds -= minutes * 60;

        // Update the timer clock
        [elapsed setTitle:[NSString stringWithFormat:@"%.2i:%.2i:%.2i:%.2i",days,hours,minutes,seconds] forState:UIControlStateNormal];
    }
}
67
FierceMonkey

Le clignotement n'est pas causé par la minuterie en soi. La méthode UIButton setTitle: forState provoque le clignotement. Une solution simple consiste à utiliser un UIButton sans titre et à superposer un UILabel. Lorsque vous modifiez le texte UILabel, il ne clignote pas. 

16
The Tank

Définissez le type de bouton sur UIButtonTypeCustom et il ne clignote plus.

157
Quanlong

Une meilleure approche que [UIView setAnimationsEnabled:NO] pouvant affecter d'autres animations consiste à ne désactiver que l'animation de titre spécifique.

Objectif c:

[UIView performWithoutAnimation:^{
  [myButton setTitle:text forState:UIControlStateNormal];
  [myButton layoutIfNeeded];
}];

Swift 3:

UIView.performWithoutAnimation { 
    myButton.setTitle(text, for: .normal)
    myButton.layoutIfNeeded()
}
32
Cœur

*Notez s'il vous plaît *

quand "buttonType" de _button est "UIButtonTypeSystem" , le code ci-dessous est invalide

[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];

quand "buttonType" de _button est "UIButtonTypeCustom" , le code ci-dessus est valide .

29
shede333

Voir les réponses de Comment arrêter une animation UIButton indésirable sur le changement de titre? :

[UIView setAnimationsEnabled:NO];
[elapsed setTitle:[NSString stringWithFormat:@"%.2i:%.2i:%.2i:%.2i",days,hours,minutes,seconds] forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
16
Marius

Le comportement par défaut de "setTitle" est vraiment odieux!

Ma solution est:

[UIView setAnimationsEnabled:NO];
[_button layoutIfNeeded]; 
[_button setTitle:[NSString stringWithFormat:@"what" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];

De plus, dans le storyboard, sous la propriété de button, je décoche:

  • Inverse sur le point culminant
  • Surligné Ajuster l'image

Et vérifie:

  • Disabled Ajuster l'image

Testé et fonctionne sur iOS 8 aussi.

Mise à jour - Swift

Je vous suggère de créer votre bouton personnalisé et de remplacer la méthode setTitle.

class UnflashingButton: UIButton {

    override func setTitle(title: String?, forState state: UIControlState) {
        UIView.setAnimationsEnabled(false)
        self.layoutIfNeeded()
        super.setTitle(title, forState: state)
        UIView.setAnimationsEnabled(true)
    }

}
6
Luca Davanzo

Vous pouvez simplement créer une autre fonction pour UIButton pour une utilisation future aisée.

extension UIButton {
    func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState) {
        UIView.performWithoutAnimation {
            self.setTitle(title, for: controlState)
            self.layoutIfNeeded()
        }
    }
}

C'est ça!

Et définissez simplement le titre comme vous le feriez auparavant, mais remplacez setTitle par setTitleWithoutAnimation

5
Daniel Tseng

Un autre tour

@IBOutlet private weak var button: UIButton! {
    didSet {
        button.setTitle(title, for: .normal)
    }
}

Cela ne fonctionne que si vous connaissez la valeur du titre sans effectuer d'appels d'API. Le titre du bouton sera défini avant le chargement de la vue afin que vous ne puissiez pas voir l'animation

0
TunaTheDog

Je suis novice en codage et Stackoverflow, vous n'avez donc pas assez de réputation pour commenter directement sur https://stackoverflow.com/users/4673064/daniel-tseng excellente réponse. Je dois donc écrire ma propre nouvelle réponse, et voici ceci:

extension UIButton {
    func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState) {
        UIView.performWithoutAnimation {
            self.setTitle(title, for: controlState)
            self.layoutIfNeeded()
        }
    }
}

Fonctionne très bien, SAUF:

Si tous mes appels ultérieurs dans le code "setTitleWithoutAnimation" ne spécifient pas d'expéditeur, je reçois ces messages étranges liés à CoreMedia ou CoreData, par exemple: "Échec de l'héritage des autorisations CoreMedia de 2526: (null)"

C’est probablement assez basique pour coder et iOS, mais pour moi en tant que nouveau codeur, cela m’a envoyé sur une piste de lapin pendant un moment, comme dans: Today Extension Impossible d’hériter des autorisations CoreMedia de , où les gens avaient des réponses intéressantes. mais cela n'a pas atteint la racine de mon problème.

Alors, j’ai finalement trouvé que je devais passer au travers et donner les paramètres de mes fonctions sans paramètre, c’est-à-dire que je devais spécifier un expéditeur. Cet expéditeur peut être UIButton, Any ou AnyObject. Toutes ces solutions ont fonctionné, mais au final, il semble exister un conflit entre l'ajout d'une extension de bouton avec "self" et le fait de ne pas indiquer spécifiquement plus tard qu'un bouton l'utilise.

Encore une fois, probablement basique, mais nouveau pour moi, alors j’ai pensé que cela valait la peine d’être partagé.

0
Ian Hanson

Essayez ceci, cela fonctionne dans les nouvelles versions d'IOS:

class CustomButtonWithNoEffect : UIButton {
    override func setTitle(_ title: String?, for state: UIControlState) {
        UIView.performWithoutAnimation {
            super.setTitle(title, for: state)
            super.layoutIfNeeded()
        }
    }

}
0
Andras Karpati