uibutton - ios - 如何防止UIButton在更新标题时闪烁

当我在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];


 }


}



时间:

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

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

objective-c :


[UIView performWithoutAnimation:^{


 [myButton setTitle:text forState:UIControlStateNormal];


 [myButton layoutIfNeeded];


}];



Swift:


UIView.performWithoutAnimation { 


 myButton.setTitle(text, for: .normal)


 myButton.layoutIfNeeded()


}



*请注意*

当_button的 _""buttonType "是"UIButtonTypeSystem "时,下面的代码无效:


[UIView setAnimationsEnabled:NO];


[_button setTitle:@"title" forState:UIControlStateNormal];


[UIView setAnimationsEnabled:YES];



当_button的 _""buttonType "是"UIButtonTypeCustom "时,上面的代码是有效的。

默认的"settitle"行为绝对是可恶的!

我的解决方案是:


[UIView setAnimationsEnabled:NO];


[_button layoutIfNeeded]; 


[_button setTitle:[NSString stringWithFormat:@"what" forState:UIControlStateNormal];


[UIView setAnimationsEnabled:YES];



另外,在Storyboard中,在按钮的属性下取消选中:

  • 突出显示时反转
  • 突出显示调整图像

并检查:

  • 禁用调整图像

已测试并在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)


 }



}



你可以简单地为UIButton制作另一个功能,以便日后使用。


extension UIButton {


 func setTitleWithoutAnimation(_ title: String?, for controlState: UIControlState) {


 UIView.performWithoutAnimation {


 self.setTitle(title, for: controlState)


 self.layoutIfNeeded()


 }


 }


}



就是这样!

将标题设置为之前的样子用setTitleWithoutAnimation替换setTitle

试试这个,它在新版IOS中工作:


class CustomButtonWithNoEffect : UIButton {


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


 UIView.performWithoutAnimation {


 super.setTitle(title, for: state)


 super.layoutIfNeeded()


 }


 }



}



另一个技巧


@IBOutlet private weak var button: UIButton! {


 didSet {


 button.setTitle(title, for: .normal)


 }


}



只有知道标题的值而不进行任何API调用时,这个操作才有效。

...