如何在标题更改时停止不需要的UIButton动画?

时间:2013-09-22 17:10:02

标签: objective-c swift ios7 uibutton uikit

在iOS 7中,我的UIButton游戏在错误的时间进行动画制作 - 迟到。这个问题在iOS 6上没有出现。我只是使用:

[self setTitle:text forState:UIControlStateNormal];

我希望这种情况立即发生,没有空框。这种眨眼特别令人分心,并引起人们对其他动画的注意。

24 个答案:

答案 0 :(得分:236)

使用performWithoutAnimation:方法,然后立即强制布局,而不是稍后。

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

答案 1 :(得分:150)

这适用于自定义按钮:

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

对于系统按钮,您需要在重新启用动画之前添加它(谢谢@Klaas):

[_button layoutIfNeeded];

答案 2 :(得分:63)

将按钮类型更改为自定义表单界面构建器。

enter image description here

这对我有用。

答案 3 :(得分:57)

请注意:

当_button的“ buttonType ”为“UIButtonTypeSystem”时,代码无效

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

当_button的“ buttonType ”为“UIButtonTypeCustom”时,上面的代码有效

答案 4 :(得分:57)

在Swift中你可以使用:

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

答案 5 :(得分:48)

从iOS 7.1开始,唯一适合我的解决方案是初始化类型为UIButtonTypeCustom的按钮。

答案 6 :(得分:18)

所以我找到了有效的解决方案:

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

首先我们更改按钮的标题,然后调整此标题的按钮

答案 7 :(得分:13)

将按钮类型设置为UIButtonTypeCustom并且它将停止闪烁

答案 8 :(得分:12)

我做了一个Swift扩展来执行此操作:

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

        setTitle(title, forState: .Normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}

适用于iOS 8和9,UIButtonTypeSystem

(代码适用于Swift 2,Swift 3和Objective-C应该类似)

答案 9 :(得分:7)

将UIButton类型设置为Custom。这应该可以删除淡入和淡出动画。

答案 10 :(得分:7)

类型为system

UIButton在setTitle(_:for:)上具有隐式动画。您可以通过两种不同的方式修复它:

  1. 通过代码或Interface Builder将按钮类型设置为custom
let button = UIButton(type: .custom)

enter image description here

  1. 从代码中禁用动画:
UIView.performWithoutAnimation {
    button.setTitle(title, for: .normal)
    button.layoutIfNeeded()
}

答案 11 :(得分:5)

您只需创建“自定义”按钮,即可在更改标题时停止动画。

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

您也可以在Storyboard复选框中执行此操作: 选择故事板中的按钮 - >选择属性检查器(左起第四个) - >在“类型”下拉菜单中,选择“自定义”而不是可能选择的“系统”。

祝你好运!

答案 12 :(得分:4)

通常只是将按钮类型设置为Custom适用于我,但由于其他原因,我需要子类化UIButton并将按钮类型设置回默认值(系统),因此闪烁再次出现。

在更改标题之前设置UIView.setAnimationsEnabled(false),然后再设置为true,之后无论我是否调用self.layoutIfNeeded()都不会眨眼。

这个,只有按照以下确切的顺序,适用于iOS 9和10 beta:

1)为UIButton创建一个子类(不要忘记在Storyboard中为按钮设置自定义类)。

2)按如下方式覆盖setTitle:forState:

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

    UIView.performWithoutAnimation({

        super.setTitle(title, forState: state)

        self.layoutIfNeeded()
    })
}

在Interface Builder中,您可以将按钮类型保留为System,无需将其更改为自定义类型即可使用此方法。

我希望这可以帮助别人,我已经用烦人的闪烁按钮挣扎了很长时间,我希望避免让别人使用它;)

答案 13 :(得分:3)

您可以从标题标签的图层中删除动画:

    [[[theButton titleLabel] layer] removeAllAnimations];

答案 14 :(得分:1)

Xhacker Liu的Swift 4版本答案

import Foundation
import UIKit
extension UIButton {
    func setTitleWithOutAnimation(title: String?) {
        UIView.setAnimationsEnabled(false)

        setTitle(title, for: .normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
} 

答案 15 :(得分:0)

在UITabBarController中的视图控制器中更改按钮标题时,我遇到了丑陋的动画问题。 最初在故事板中设置的标题在淡入新值之前出现了一段时间。

我想遍历所有子视图并使用按钮标题作为键来获取NSLocalizedString的本地化值,例如;

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

}

我发现触发动画的内容实际上是对btn.titleLabel.text的调用。 因此,为了仍然使用故事板并使组件动态地本地化,我确保将每个按钮的Restoration ID(在Identity Inspector中)设置为与标题相同,并将其用作键而不是标题;

for(UIView *v in view.subviews) {

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

}

不理想,但有效..

答案 16 :(得分:0)

您实际上可以在动画块之外设置标题,只需确保在performWithoutAnimation中调用layoutIfNeeded()

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()
}

如果您有一堆按钮,请考虑在超级视图上调用layoutIfNeeded()

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

答案 17 :(得分:0)

我发现此解决方法也适用于 UIButtonTypeSystem ,但仅在按钮启用时才会起作用。

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

因此,如果您在设置标题时需要禁用该按钮,则必须添加这些内容。

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

(iOS 7,Xcode 5)

答案 18 :(得分:0)

Xhacker Liu扩展转换为Swift 3:

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

        setTitle(title, for: .normal)

        layoutIfNeeded()
        UIView.setAnimationsEnabled(true)
    }
}

答案 19 :(得分:0)

雨燕5

myButton.titleLabel?.text = "title"
myButton.setTitle("title", for: .normal)

答案 20 :(得分:-1)

我得到了一组答案:

[[[button titleLabel] layer] removeAllAnimations];

    [UIView performWithoutAnimation:^{

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

    }];

答案 21 :(得分:-1)

结合以上优秀答案会导致 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];
}

答案 22 :(得分:-1)

也许生成2个动画和2个按钮是一个更好的解决方案,以避免出现动画和更改按钮文本时出现的问题?

我创建了第二个uibutton并生成了2个动画,此解决方案无需使用hickup。

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

答案 23 :(得分:-1)

Swift中动画按钮标题更改的便捷扩展,可以很好地与默认实现配合使用:

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)
    }
  }
}