5

2つのuislidersを使用してcoreBluetoothを使用して送信される値を制御するiPhoneアプリを作成しています。スライダーをすばやく動かすと、レシーバーで1つの値がフリーズします。これは、値の変更イベントが頻繁にトリガーされるため、書き込みコマンドがスタックして最終的に破棄されるためと考えられます。イベントが頻繁にトリガーされないようにするにはどうすればよいですか?

編集:

これが問題の明確化です。Bluetooth接続は105msごとにコマンドを送信します。その間にユーザーが一連のイベントを生成した場合、それらはキューに入れられているように見えます。接続イベント間に生成された値をすべて破棄し、105ミリ秒ごとに1つ送信したいと思います。

これは基本的に私が今していることです:

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

3 に答える 3

0

単なるアイデアですが、値が変更されたイベントを送信することはできません。最後の送信の値を変数に格納し、最後に送信された値が現在のスライダー値と異なるかどうかをチェックするタイマーをバックグラウンドで実行して、新しい値を送信することができます。タイマーは105ミリ秒ごとに起動するように設定でき、新しい値が最後に送信された値と異なる場合にのみ、105ミリ秒ごとに値を送信します。

于 2012-07-04T09:13:11.180 に答える
0

それでもトリガーするのは理にかなっていると思います...あなたの場合、現在の値と前の値の間のデルタをチェックすることです。例えば:

  • 現在の値->5。
  • 次の値->6。
  • デルタ1

ちょっとした擬似コード:

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

私はこれをテストしませんでしたが、あなたはその考えを理解していると思います。

于 2012-07-04T07:38:04.503 に答える
0

複雑になり、タイムスタンプまたは新しい値と古い値の差がしきい値より大きいかどうかに基づいて、スライダーからの入力をフィルタリングすることができます。

より簡単な方法は、touchEndedという別のイベントを使用することです。そうすれば、すべての中間値ではなく、最終値のみを送信します。

アプリには適さないかもしれませんが、何をする必要があるのか​​が完全には明確ではありません。

于 2012-07-04T07:48:42.100 に答える