更新标题时如何防止UIButton闪烁

时间:2013-10-15 00:42:05

标签: uibutton ios7

当我在UIButton上调用setTitle时,该按钮在iOS 7中闪烁。我尝试设置myButton.highlighted = NO,但这并没有阻止按钮闪烁。

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

myButton.highlighted = NO;

以下是我如何设置更新标题的计时器:

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

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

以下是实际更新标题的方法:

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

10 个答案:

答案 0 :(得分:168)

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

答案 1 :(得分:35)

比可能影响其他动画的[UIView setAnimationsEnabled:NO]更好的方法是仅禁用特定的标题动画。

目标-C:

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

夫特:

UIView.performWithoutAnimation { 
    myButton.setTitle(text, for: .normal)
    myButton.layoutIfNeeded()
}

答案 2 :(得分:29)

* 请注意*

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

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

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

答案 3 :(得分:17)

请参阅How to stop unwanted UIButton animation on title change?的回复:

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

答案 4 :(得分:16)

闪烁不是由计时器本身引起的。 UIButton方法setTitle:forState导致闪烁。一个简单的解决方法是使用没有标题的UIButton并叠加UILabel。更改UILabel文本时,它不会闪烁。

答案 5 :(得分:6)

默认" setTitle" 行为绝对是可恨的!

我的解决方案是:

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

此外,在故事板中,在按钮的属性下,我取消选中:

  • 突出显示
  • 突出显示调整图像

并检查:

  • 已禁用调整图像

经过测试并处理 iOS 8

更新 - Swift

我建议您创建自定义按钮并覆盖 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 :(得分:6)

您只需为UIButton创建另一个功能,以便日后使用。

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

就是这样!

只需像以前一样设置标题,但将setTitle替换为setTitleWithoutAnimation

答案 7 :(得分:1)

尝试一下,这可以在新版本的IOS中使用:

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

}

答案 8 :(得分:0)

我是编码和Stackoverflow的新手,因此没有足够的声誉直接评论以扩展https://stackoverflow.com/users/4673064/daniel-tseng出色的答案。所以我必须写自己的新答案,就是这样:

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

效果很好,除了:

如果稍后我在“setTitleWithoutAnimation”的代码中的所有调用都没有指定发件人,那么我会收到与CoreMedia或CoreData相关的这些奇怪的消息,例如“无法从2526继承CoreMedia权限:( null)”< / p>

这对于编码和iOS来说可能是非常基础的,但对于我来说,作为一个新的编码器,它让我在兔子路上走了一段时间,如:Today Extension Failed to inherit CoreMedia permissions from,人们有了有趣的答案,但那并没有找到问题的根源。

所以我终于发现我必须通过并提供我的无参数函数参数,即我必须指定一个发送者。该发件人可以是UIButton,Any或AnyObject。所有这些都有效,但最终在添加按钮扩展名与“self”之间似乎存在冲突,而后面没有具体说明按钮正在使用它。

同样,可能是基本的,但对我来说是新的,所以我认为值得分享。

答案 9 :(得分:0)

另一把戏

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

仅当您知道标题的值而不进行任何API调用时,此方法才有效。按钮的标题将在加载视图之前设置,因此您不会看到动画