我正在编写一个 iPhone 应用程序,它使用两个 uislider 来控制使用 coreBluetooth 发送的值。如果我快速移动滑块,一个值会在接收器处冻结,大概是因为“值更改”事件触发得太频繁,导致写入命令堆积起来并最终被丢弃。如何确保事件不会频繁触发?
编辑:
这里对问题进行澄清;蓝牙连接每 105 毫秒发送一次命令。如果用户在那段时间生成一堆事件,他们似乎会排队。我想丢弃连接事件之间生成的任何值,而只是每 105 毫秒发送一个值。
这基本上就是我现在正在做的事情:
-(IBAction) sliderChanged:(UISlider *)sender{
static int8_t value = 0;
int8_t new_value = (int8_t)sender.value;
if ( new_value > value + threshold || new_value < value - threshold ) {
value = new_value;
[btDevice writeValue:value];
}
}
我要问的是如何实现类似的事情
-(IBAction) sliderChanged:(UISlider *)sender{
static int8_t value = 0;
if (105msHasPassed) {
int8_t new_value = (int8_t)sender.value;
if ( new_value > value + threshold || new_value < value - threshold ) {
value = new_value;
[btDevice writeValue:value];
}
}
}
我想仍然触发它们确实有意义......在你的情况下我会做的是检查当前值和前一个值之间的增量。例如:
只是一些伪代码:
if(delta>5){
//do your stuff
}
我可能不会这样做,但是:
-(void)sliderValueChanged:(UISlider *)sender{
[self performSelector:@selector(removeAction:) withObject:sender afterDelay:0.3];
// Do your stuff
}
- (void)removeAction:(UISlider *)sender{
[sender removeTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
[self performSelector:@selector(addAction:) withObject:sender afterDelay:0.3];
}
- (void)addAction:(UISlider *)sender{
[mySlider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
}
我没有测试过这个,但我想你已经明白了。
您可以变得复杂,并根据某个时间戳或新值与旧值之间的差异是否大于某个阈值来过滤滑块的输入。
更简单的方法是使用不同的事件:touchEnded。这样您只发送最终值,而不发送所有中间值。
可能不适合您的应用程序,但尚不完全清楚您需要做什么。
只是一个想法,但您可以做的不是发送值更改事件。您可以将上次传输的值存储在变量中,然后可以在后台运行一个计时器,检查上次发送的值是否与当前滑块值不同,如果不同则发送新值。计时器可以设置为每 105 毫秒触发一次,如果新值与上次发送的值不同,则只会每 105 毫秒发送一次值。
您还可以使用滑块上的 isContinously 属性来仅在释放拇指时获取事件。