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.
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];
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];
}];
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 .
changer le type de bouton à custom form interface builder.
ça a marché pour moi.
dans Swift, vous pouvez utiliser:
UIView.performWithoutAnimation {
self.someButtonButton.setTitle(newTitle, forState: .normal)
self.someButtonButton.layoutIfNeeded()
}
à partir de ios 7.1 la seule solution qui a fonctionné pour moi était d'initialiser le bouton avec le type UIButtonTypeCustom
.
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
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)
Réglez le type de bouton sur UIButtonTypeCustom et il cessera de clignoter
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!
vous pouvez supprimer les animations de la couche titre:
[[[theButton titleLabel] layer] removeAllAnimations];
définit le type UIButton comme personnalisé. Cela devrait supprimer les animations.
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 ;)
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)
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..
, 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()
}
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)
}
}
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];
}
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;}];
j'ai obtenu de travailler avec une combinaison de réponses:
[[[button titleLabel] layer] removeAllAnimations];
[UIView performWithoutAnimation:^{
[button setTitle:@"Title" forState:UIControlStateNormal];
}];
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)
}
}
}