Comment arrêter l'animation UIButton non désirée sur le changement de titre?

Dans iOS 7 mon UIButton les titres sont l'animation et au mauvais temps de retard. Ce problème n'apparaît pas sur iOS 6. J'utilise juste:

[self setTitle:text forState:UIControlStateNormal];

je préférerais que cela arrive instantanément et sans cadre vierge. Ce clignement est particulièrement distrayant et éloigne l'attention des autres animations.

172
demandé sur pkamb 2013-09-22 21:10:01

21 réponses

cela fonctionne pour les boutons personnalisés:

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

pour les boutons système, vous devez ajouter ceci avant de réactiver les animations (merci @Klaas):

[_button layoutIfNeeded];
140
répondu Jacob K 2016-03-21 13:53:32

utilisez la méthode performWithoutAnimation: et forcez la disposition à se produire immédiatement au lieu de plus tard.

[UIView performWithoutAnimation:^{
  [self.myButton setTitle:text forState:UIControlStateNormal];
  [self.myButton layoutIfNeeded];
}];
214
répondu Snowman 2015-06-28 18:35:01

s'il vous Plaît note :

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

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

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

57
répondu shede333 2013-12-21 11:24:52

changer le type de bouton à custom form interface builder.

enter image description here

ça a marché pour moi.

52
répondu Christos Hadjikyriacou 2015-05-21 12:19:33

dans Swift, vous pouvez utiliser:

UIView.performWithoutAnimation {
    self.someButtonButton.setTitle(newTitle, forState: .normal)
    self.someButtonButton.layoutIfNeeded()
}
48
répondu Paulw11 2017-08-07 02:15:38

à partir de ios 7.1 la seule solution qui a fonctionné pour moi était d'initialiser le bouton avec le type UIButtonTypeCustom .

44
répondu Norbert 2014-04-22 20:52:37

donc je trouve la solution travaillée:

_logoutButton.titleLabel.text = NSLocalizedString(@"Logout",);
[_logoutButton setTitle:_logoutButton.titleLabel.text forState:UIControlStateNormal];

dans un premier temps, nous changeons le titre du bouton, puis redimensionnons le bouton pour ce titre

18
répondu dubenko 2014-04-22 07:15:20

j'ai fait une extension rapide pour faire ceci:

extension UIButton {
    func setTitleWithoutAnimation(title: String?) {
        UIView.setAnimationsEnabled(false)

        setTitle(title, forState: .Normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}

fonctionne pour moi sur iOS 8 et 9, avec UIButtonTypeSystem .

(le code est pour Swift 2, Swift 3 et Objectif-C devrait être similaire)

13
répondu Xhacker Liu 2017-05-22 02:03:17

Réglez le type de bouton sur UIButtonTypeCustom et il cessera de clignoter

11
répondu arunjos007 2016-02-10 09:29:32

vous pouvez simplement créer le bouton personnalisé et il s'arrêtera animer tout en changeant le titre.

        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setTitle:@"the title" forState:UIControlStateNormal];

vous pouvez aussi le faire dans la case Storyboard: sélectionnez le bouton dans storyboard -> sélectionnez les attributs inspector (quatrième à partir du côté gauche) -> dans le menu déroulant "Type", sélectionnez "Custom" au lieu de "System" qui a probablement été sélectionné.

bonne chance!

6
répondu Mendy 2014-06-16 11:06:00

vous pouvez supprimer les animations de la couche titre:

    [[[theButton titleLabel] layer] removeAllAnimations];
4
répondu Jacksonh 2014-04-23 17:47:56

définit le type UIButton comme personnalisé. Cela devrait supprimer les animations.

3
répondu Amit Tandel 2017-12-15 09:07:50

règle générale, il suffit de régler le type de bouton sur mesure fonctionne pour moi, mais pour d'autres raisons, j'ai eu besoin de sous-classe UIButton et de mettre le type de bouton à nouveau à la valeur par défaut (Système), de sorte que le clignotement réapparut.

paramétrage UIView.setAnimationsEnabled(false) avant de changer le titre et puis à nouveau vrai après cela n'a pas évité le clignotement pour moi, Peu importe si j'ai appelé self.layoutIfNeeded() ou non.

cela, et seulement ceci dans l'ordre suivant, a fonctionné pour moi avec iOS 9 et 10 bêta:

1) Créer une sous-classe pour UIButton (n'oubliez pas de définir la classe personnalisée pour le bouton dans le Storyboard aussi).

2) Remplacer setTitle:forState: comme suit:

override func setTitle(title: String?, forState state: UIControlState) {

    UIView.performWithoutAnimation({

        super.setTitle(title, forState: state)

        self.layoutIfNeeded()
    })
}

dans Interface Builder, vous pouvez laisser le type de bouton au système, pas besoin de le changer pour le type personnalisé pour cette approche de travail.

j'espère que cela aide quelqu'un d'autre, j'ai lutté pendant si longtemps avec l'ennuyeux, clignotant des boutons qui je l'espère, d'éviter à d'autres ;)

2
répondu cdf1982 2016-08-09 10:00:38

j'ai trouvé que cette solution fonctionne avec UIButtonTypeSystem aussi bien, mais ne fonctionnera que si le bouton est activé pour une raison quelconque.

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

vous devrez donc les ajouter si vous avez besoin que le bouton soit désactivé lors de la définition de son titre.

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

(iOS 7, Xcode 5)

1
répondu sCha 2014-02-11 12:59:06

j'ai eu le problème d'animation moche en changeant les titres de bouton dans les contrôleurs de vue au sein d'un UITabBarController. Les titres qui étaient à l'origine définis dans le storyboard sont apparus pendant un court moment avant de s'estomper dans leurs nouvelles valeurs.

j'ai voulu itérer à travers toutes les sous-vues et utiliser les titres de boutons comme touches pour obtenir leurs valeurs localisées avec NSLocalizedString, tels que;

for(UIView *v in view.subviews) {

    if ([v isKindOfClass:[UIButton class]]) {
        UIButton *btn = (UIButton*)v;
        NSString *newTitle = NSLocalizedString(btn.titleLabel.text, nil);
        [btn setTitle:newTitle];
    }

}

j'ai découvert que ce qui déclenche le l'animation est vraiment l'appel à btn.titleLabel.texte. Donc, pour toujours utiliser les storyboards et avoir les composants localisés dynamiquement comme ceci, je m'assure de régler l'ID de restauration de chaque bouton (dans L'Inspecteur D'identité) au même titre que le titre et l'utiliser comme clé au lieu du titre;

for(UIView *v in view.subviews) {

    if ([v isKindOfClass:[UIButton class]]) {
        UIButton *btn = (UIButton*)v;
        NSString *newTitle = NSLocalizedString(btn.restorationIdentifier, nil);
        [btn setTitle:newTitle];
    }

}

pas idéal, mais ça marche..

1
répondu Michael 2014-05-24 21:35:39

, Vous pouvez effectivement mettre le titre en dehors d'un bloc d'animation, juste être sûr d'appeler layoutIfNeeded() à l'intérieur d'un performWithoutAnimation:

button1.setTitle("abc", forState: .Normal)
button2.setTitle("abc", forState: .Normal)
button3.setTitle("abc", forState: .Normal)
UIView.performWithoutAnimation {
    self.button1.layoutIfNeeded()
    self.button2.layoutIfNeeded()
    self.button3.layoutIfNeeded()
}

si vous avez un tas de boutons, considérez simplement appeler layoutIfNeeded() sur la vue super:

button1.setTitle("abc", forState: .Normal)
button2.setTitle("abc", forState: .Normal)
button3.setTitle("abc", forState: .Normal)
UIView.performWithoutAnimation {
    self.view.layoutIfNeeded()
}
1
répondu Senseful 2015-07-29 19:19:44

l'extension Xhacker Liu convertie en Swift 3:

extension UIButton {
    func setTitleWithoutAnimation(title: String?) {
        UIView.setAnimationsEnabled(false)

        setTitle(title, for: .normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}
1
répondu Paweł 2016-11-03 12:42:23

la combinaison des réponses ci-dessus donne les réponses suivantes pour UIButtonTypeSystem :

if (_button.enabled)
{
    [UIView setAnimationsEnabled:NO];
    [_button setTitle:@"title" forState:UIControlStateNormal];
    [UIView setAnimationsEnabled:YES];
}
else // disabled
{
    [UIView setAnimationsEnabled:NO];
    _button.enabled = YES;
    [_button setTitle:@"title" forState:UIControlStateNormal];
    _button.enabled = NO;
    [UIView setAnimationsEnabled:YES];
}
0
répondu AppsolutEinfach 2014-02-18 14:36:04

peut-être générer 2 animations et 2 boutons est une meilleure solution, pour éviter le problème qui apparaît avec l'animation et la modification du texte d'un bouton?

j'ai créé un second uibutton et généré 2 Animations, cette solution fonctionne sans hickups.

    _button2.hidden = TRUE;
    _button1.hidden = FALSE;

    CGPoint startLocation = CGPointMake(_button1.center.x, button1.center.y - 70);
    CGPoint stopLocation  = CGPointMake(_button2.center.x, button2.center.y- 70);


    [UIView animateWithDuration:0.3 animations:^{ _button2.center = stopLocation;} completion:^(BOOL finished){_button2.center = stopLocation;}];
    [UIView animateWithDuration:0.3 animations:^{ _button1.center = startLocation;} completion:^(BOOL finished){_button1.center = startLocation;}];
0
répondu coda 2014-03-13 20:29:12

j'ai obtenu de travailler avec une combinaison de réponses:

[[[button titleLabel] layer] removeAllAnimations];

    [UIView performWithoutAnimation:^{

        [button setTitle:@"Title" forState:UIControlStateNormal];

    }];
0
répondu Jasper 2015-02-17 12:16:37

une extension commode pour le changement de titre de bouton animé dans Swift qui se joue bien avec l'implémentation par défaut:

import UIKit

extension UIButton {
  /// By default iOS animated the title change, which is not desirable in reusable views
  func setTitle(_ title: String?, for controlState: UIControlState, animated: Bool = true) {
    if animated {
      setTitle(title, for: controlState)
    } else {
      UIView.setAnimationsEnabled(false)
      setTitle(title, for: controlState)
      layoutIfNeeded()
      UIView.setAnimationsEnabled(true)
    }
  }
}
0
répondu Richard Topchiy 2018-07-31 14:46:08