更新标题时如何防止UIButton闪烁
Posted
技术标签:
【中文标题】更新标题时如何防止UIButton闪烁【英文标题】:How to prevent UIButton from flashing when updating the title 【发布时间】:2013-10-15 00:42:05 【问题描述】:当我在 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];
【问题讨论】:
它不应该闪烁。您是否尝试在后台线程上执行此操作? 是的,它被设置在一个计时器中以每秒更新一次按钮标题(我认为这是创建自己的线程) 定时器只有在你设置它们的情况下才能在单独的线程上运行。我们可以看看标题更新的方法以及您如何设置计时器吗? 我将请求的代码添加到主要问题 How to stop unwanted UIButton animation on title change?的可能重复 【参考方案1】:将按钮类型设置为UIButtonTypeCustom,它将停止闪烁
【讨论】:
这确实应该是首选答案。最简单的解决方案。它的工作原理。 同意。我尝试了很多其他解决方案,这就是它自己完成的事情。 这应该是公认的答案。迄今为止最简单的解决方案。 像魅力一样工作!谢谢 我认为这是一个非常好的解决方案,无需为此编写任何代码。【参考方案2】:比[UIView setAnimationsEnabled:NO]
可能影响其他动画更好的方法是只禁用特定的标题动画。
目标-C:
[UIView performWithoutAnimation:^
[myButton setTitle:text forState:UIControlStateNormal];
[myButton layoutIfNeeded];
];
斯威夫特:
UIView.performWithoutAnimation
myButton.setTitle(text, for: .normal)
myButton.layoutIfNeeded()
【讨论】:
刚刚在最新的 iOS 上尝试了 Swift 解决方案 - 效果很好。 救星。干杯! 刚刚在 Swift 3 中尝试过这个,它可以在不使用 layoutIfNeeded() 的情况下工作 这应该是毫无疑问的公认答案! 这是最好的方法。很好的答案!【参考方案3】:*请注意*
当_button的“buttonType”为“UIButtonTypeSystem”时,下面的代码无效:
[UIView setAnimationsEnabled:NO];
[_button setTitle:@"title" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
当_button的“buttonType”为“UIButtonTypeCustom”时,上述代码为有效。
【讨论】:
【参考方案4】:查看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];
【讨论】:
@FierceMonkey 尝试添加对layoutIfNeeded
:[elapsed layoutIfNeeded];
的呼叫。这消除了我的情况下的闪烁。
layoutIfNeeded 为我做了。
这似乎是一个相当肮脏的解决方法,但是 layoutIfNeeded
似乎正在工作【参考方案5】:
您可以简单地为 UIButton 制作另一个函数以方便将来使用。
extension UIButton
func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState)
UIView.performWithoutAnimation
self.setTitle(title, for: controlState)
self.layoutIfNeeded()
就是这样!
只需像以前一样设置标题,但将 setTitle
替换为 setTitleWithoutAnimation
【讨论】:
【参考方案6】:默认的“setTitle”行为绝对是可恶的!
我的解决办法是:
[UIView setAnimationsEnabled:NO];
[_button layoutIfNeeded];
[_button setTitle:[NSString stringWithFormat:@"what" forState:UIControlStateNormal];
[UIView setAnimationsEnabled:YES];
另外,在情节提要中,在按钮的属性下,我取消选中:
高光反转 突出显示的调整图像然后检查:
禁用调整图像在 iOS 8 上也经过测试和工作。
更新 - 斯威夫特
我建议您创建自定义按钮并覆盖 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)
【讨论】:
我尝试了这种方法(子类化、覆盖 setTitle:forState: 和禁用启用 UIView.setAnimationsEnabled)。在 iOS 9 和 10 测试版中不适合我。如果我只禁用动画,它就可以工作,但是每个 UIView 都会丢失它们......【参考方案7】:试试这个,这适用于较新版本的 IOS:
class CustomButtonWithNoEffect : UIButton
override func setTitle(_ title: String?, for state: UIControlState)
UIView.performWithoutAnimation
super.setTitle(title, for: state)
super.layoutIfNeeded()
【讨论】:
【参考方案8】:我是编码和 *** 的新手,因此没有足够的声誉直接评论以扩展 https://***.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)”
这对于编码和 iOS 来说可能是非常基础的,但对于我作为一个新编码员来说,它让我在兔子路上走了一段时间,例如:Today Extension Failed to inherit CoreMedia permissions from,人们有有趣的答案,但没有达到我的问题的根源。
所以我终于发现我必须通过并给我的无参数函数参数,即我必须指定一个发送者。该发送者可以是 UIButton、Any 或 AnyObject。所有这些都有效,但最终似乎在添加带有“self”的按钮扩展名和稍后没有具体说明按钮正在使用它之间存在冲突。
再次,可能是基本的,但对我来说是新的,所以我认为它值得分享。
【讨论】:
【参考方案9】:另一个技巧
@IBOutlet private weak var button: UIButton!
didSet
button.setTitle(title, for: .normal)
这只有在您知道标题的值而不进行任何 API 调用时才有效。按钮的标题将在视图加载之前设置,因此您不会看到动画
【讨论】:
以上是关于更新标题时如何防止UIButton闪烁的主要内容,如果未能解决你的问题,请参考以下文章