如何刷新UI线程上的button?
在我的用户界面上有一个button,每按下一次button,我就会每隔800毫秒闪一下(打开,然后再closures)。 我用下面的代码做到这一点:
- (void)flickEmergencyButton { // Check whether an emergency is in progress... if (model.emergencyInProgress) { // ...and if so, flick the state self.emergencyButton.selected = !self.emergencyButton.selected; // Make this method be called again in 800ms [self performSelector:@selector(flickEmergencyButton) withObject:nil afterDelay:0.8]; } else { // ...otherwise, turn the button off self.emergencyButton.selected = NO; } }
…除了以下function外,其他function都能正常工作:在用户界面上还有一个UIScrollView,当用户将手指放在上面并滚动时,button会冻结。 虽然我完全明白这是为什么,我不知道该怎么办。
performSelector:withObject:afterDelay
消息调度要在当前线程(即主线程)上发送的消息,即。 用户界面踩踏,因此不会处理消息,直到所有其他用户界面活动结束。 正确? 但我需要在UI线程上这样做,因为我不能select/取消任何其他线程上的button,对不对? 那么这里的解决scheme是什么?
我会build议使用核心animation。 尝试这样的事情:
-(void) flash{ [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:0.3f]; [UIView setAnimationCurve:UIViewAnimationCurveLinear]; if( emergency ){ // Start flashing [UIView setAnimationRepeatCount:1000]; [UIView setAnimationRepeatAutoreverses:YES]; [btn setAlpha:0.0f]; }else{ // Stop flashing [UIView setAnimationBeginsFromCurrentState:YES]; [UIView setAnimationRepeatCount:1]; [btn setAlpha:1.0f]; } emergency = !emergency; [UIView commitAnimations]; }
btn被声明为
@property(nonatomic, retain) IBOutlet UIButton *btn;
紧急情况是一个简单的BOOLvariables。
调用闪光灯开始并停止animation。
在这个例子中,为了简单起见,我们给alpha属性设置了animation,但是你可以像按照Sam的回答一样使用button背景颜色,或者你喜欢的任何属性。
希望能帮助到你。
更新:
关于在两个图像之间进行转换,请尝试调用imageFlash
而不是flash
:
-(void) imageFlash{ CABasicAnimation *imageAnimation = [CABasicAnimation animationWithKeyPath:@"contents"]; [btn setImage:normalState forState:UIControlStateNormal]; if( emergency ){ imageAnimation.duration = 0.5f; imageAnimation.repeatCount = 1000; }else{ imageAnimation.repeatCount = 1; } imageAnimation.fromValue = (id)normalState.CGImage; imageAnimation.toValue = (id)emergencyState.CGImage; [btn.imageView.layer addAnimation:imageAnimation forKey:@"animateContents"]; [btn setImage:normalState forState:UIControlStateNormal]; // Depending on what image you want after the animation. emergency = !emergency; }
凡normalState
和emergencyState
是你想要使用的图像:
声明为:
UIImage *normalState; UIImage *emergencyState;
分配图像:
normalState = [UIImage imageNamed:@"normal.png"]; emergencyState = [UIImage imageNamed:@"alert.png"];
祝你好运!
虽然这感觉像是一个CoreAnimation
的工作(也许animation的自定义UIControl
的backgroundColor
),你可以用一个NSTimer
在适当的运行循环模式下运行来实现这一点。
前
NSTimer *timer = [NSTimer timerWithTimeInterval:0.8f target:self selector:@selector(flicker:) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
而当你想停止animation:
[timer invalidate], timer = nil; button.selected = NO;
通过将计时器添加到所有NSRunLoopCommonModes
,您不仅可以将其添加到默认的运行循环模式,而且还可以在用户交互持续处理模式( UITrackingRunLoopMode
)中将其添加到模式中。
一般来说, 苹果的文档给出了运行循环模式和运行循环的更全面的解释。