Comment arrêter une animation UIButton indésirable sur le changement de titre?

Dans iOS 7, mes titres UIButton s’animent au mauvais moment, tardivement. 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 vide. Ce clignement est particulièrement distrayant et attire l’attention des autres animations.

Cela fonctionne pour les boutons personnalisés:

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

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

 [_button layoutIfNeeded]; 

Utilisez la méthode performWithoutAnimation: puis forcez la mise en page à se produire immédiatement plutôt que plus tard.

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

Notez s’il vous plaît :

lorsque ” buttonType ” de _button est “UIButtonTypeSystem” , le code ci-dessous est invalide :

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

lorsque ” buttonType ” de _button est “UIButtonTypeCustom” , le code ci-dessus est valide .

Changer le type de bouton en générateur d’interface de formulaire personnalisé.

entrer la description de l'image ici

Cela a fonctionné pour moi.

Dans Swift, vous pouvez utiliser:

 UIView.performWithoutAnimation { self.someButtonButton.setTitle(newTitle, forState: .normal) self.someButtonButton.layoutIfNeeded() } 

À partir d’iOS 7.1, la seule solution qui a fonctionné pour moi était l’initialisation du bouton avec le type UIButtonTypeCustom .

donc je trouve une solution travaillée:

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

en premier on change de titre pour le bouton, puis on redimensionne le bouton pour ce titre

J’ai fait une extension Swift pour faire ceci:

 extension UIButton { func setTitleWithoutAnimation(title: Ssortingng?) { 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 Objective-C devraient être similaires)

Définissez le type de bouton sur UIButtonTypeCustom et il cessera de clignoter

Vous pouvez simplement créer un bouton Personnaliser et cela arrêtera d’animer tout en changeant le titre.

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

vous pouvez également le faire dans la case Storyboard: sélectionnez le bouton dans le storyboard -> sélectionnez l’inspecteur d’atsortingbuts (quasortingème depuis le côté gauche) -> dans le menu déroulant «Type», sélectionnez «Personnalisé» au lieu de «Système» probablement sélectionné .

Bonne chance!

Vous pouvez supprimer les animations du calque du titre:

  [[[theButton titleLabel] layer] removeAllAnimations]; 

Définissez le type UIButton sur Personnalisé. Cela devrait supprimer les animations d’ouverture et de fermeture.

Habituellement, définir simplement le type de bouton sur Custom fonctionne pour moi, mais pour d’autres raisons, je devais sous-classer UIButton et définir le type de bouton sur la valeur par défaut (System), pour que le clignotement réapparaisse.

Définir UIView.setAnimationsEnabled(false) avant de changer le titre et ensuite à nouveau après avoir évité le clignotement pour moi, peu importe si j’ai appelé self.layoutIfNeeded() ou non.

Ceci, et seulement dans l’ordre suivant, a fonctionné pour moi avec iOS 9 et 10 beta:

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

2) Remplacer setTitle:forState: comme suit:

 override func setTitle(title: Ssortingng?, forState state: UIControlState) { UIView.performWithoutAnimation({ super.setTitle(title, forState: state) self.layoutIfNeeded() }) } 

Dans Interface Builder, vous pouvez laisser le type de bouton à System, il n’est pas nécessaire de le modifier en type personnalisé pour que cette approche fonctionne.

J’espère que cela aide quelqu’un d’autre, j’ai lutté si longtemps avec les boutons clignotants ennuyeux que j’espère éviter aux autres;)

J’ai trouvé que cette solution fonctionne également avec UIButtonTypeSystem 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 append si vous souhaitez 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)

J’ai eu le problème de l’animation lors de la modification des titres de boutons dans les contrôleurs de vue dans UITabBarController. Les titres qui étaient à l’origine définis dans le storyboard sont apparus pendant un court moment avant de s’adoucir dans leurs nouvelles valeurs.

Je voulais parcourir toutes les sous-vues et utiliser les titres de boutons comme clés pour obtenir leurs valeurs localisées avec NSLocalizedSsortingng, par exemple;

 for(UIView *v in view.subviews) { if ([v isKindOfClass:[UIButton class]]) { UIButton *btn = (UIButton*)v; NSSsortingng *newTitle = NSLocalizedSsortingng(btn.titleLabel.text, nil); [btn setTitle:newTitle]; } } 

J’ai découvert que ce qui déclenche l’animation est vraiment l’appel à btn.titleLabel.text. Donc, pour toujours utiliser les storyboards et avoir les composants dynamicment localisés comme cela, je m’assure de définir l’ID de restauration de chaque bouton (dans Identity Inspector) sur le même titre que le titre et de l’utiliser comme clé au lieu du titre;

 for(UIView *v in view.subviews) { if ([v isKindOfClass:[UIButton class]]) { UIButton *btn = (UIButton*)v; NSSsortingng *newTitle = NSLocalizedSsortingng(btn.restorationIdentifier, nil); [btn setTitle:newTitle]; } } 

Pas idéal, mais fonctionne ..

Vous pouvez réellement définir le titre en dehors d’un bloc d’animation, veillez simplement à appeler layoutIfNeeded() dans un performWeoutAnimation:

 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, pensez à 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() } 

L’extension Xhacker Liu convertie en Swift 3:

 extension UIButton { func setTitleWithoutAnimation(title: Ssortingng?) { UIView.setAnimationsEnabled(false) setTitle(title, for: .normal) layoutIfNeeded() UIView.setAnimationsEnabled(true) } } 

En combinant les bonnes réponses ci-dessus, vous pouvez résoudre le problème suivant avec 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]; } 

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

J’ai créé un deuxième uibutton et généré 2 animations, cette solution fonctionne sans aucun problème.

  _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;}]; 

Je l’ai fait fonctionner avec une combinaison de réponses:

 [[[button titleLabel] layer] removeAllAnimations]; [UIView performWithoutAnimation:^{ [button setTitle:@"Title" forState:UIControlStateNormal]; }]; 

Une extension pratique pour le changement de titre de bouton animé dans Swift qui 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: Ssortingng?, for controlState: UIControlState, animated: Bool = true) { if animated { setTitle(title, for: controlState) } else { UIView.setAnimationsEnabled(false) setTitle(title, for: controlState) layoutIfNeeded() UIView.setAnimationsEnabled(true) } } }