6

float 値をどこかに設定するために使用しているスライダーがあります。Value Changedを viewController のメソッドに接続します。その部分はうまく機能します。

ユーザーがいつコントロールに触れ始めたかを知る必要がありますが、必ずしもスライダーが変化するすべての瞬間を知る必要はありません (そのためにValue Changedイベントを受け取ります)。そこで、Touch Up Insideイベントを viewController の別のメソッドに接続しました。

問題は、ユーザーがUISliderコントロールに触れると、そのメソッドが 2 回呼び出されることです。なんてこと?UIButtonsやTouch Downのような他のタッチ イベントでは、そのようには機能しません。

私はそれを回避できると思いますが、スライダー コントロールがタッチを処理する方法のバグのようです。なぜそれが起こるのか誰か知っていますか?

ところで: Touch Up Insideが唯一の接続されたイベントであっても、ダブルタッチイベントが発生します。

4

9 に答える 9

6

今後のアップデートで壊れないように

[customSlider addTarget:self action:@selector(sliderDown:) forControlEvents:UIControlEventTouchDown];

[customSlider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventTouchUpInside];



- (void)sliderDown:(id)sender
{

    sliderused = NO;

}

- (void)sliderAction:(id)sender
{
    if(sliderused){
    return;
}

sliderused = YES;

//Your Code Here
}
于 2010-06-24T10:37:21.987 に答える
2

スライダーをサブクラス化する場合は、endTrackingWithTouch を実装して何もしないことで簡単に解決できます。

- (void) endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{}

ここでの唯一の注意点は、一部の特定の UIControlEvents が適切に起動しないことです。それらは次のものだと思いますが、どれが機能し、どれが機能しないかを確認するための特定のテストは行いませんでした。ただし、タッチの変更と内部のタッチアップは、重複した発射なしで確実に機能します。

   UIControlEventTouchDragInside     = 1 <<  2,
   UIControlEventTouchDragOutside    = 1 <<  3,
   UIControlEventTouchDragEnter      = 1 <<  4,
   UIControlEventTouchDragExit       = 1 <<  5,
于 2010-04-01T17:10:34.437 に答える
1

最も簡単な解決策は、上記のフラグ ソリューションを使用することだと思います。

(BOOL)pressed というフラグを作成し、TouchUpInside および TouchDown イベントに追加しました。したがって、押されたかどうかを確認するだけです == YES.

// On down event
pressed = YES;

// On up event
if (pressed)
{
  pressed = NO;
  // code here

}

お役に立てば幸いです。

ハミ

于 2009-08-31T17:44:40.030 に答える
1

私もこの問題を抱えていました。私の解決策は、ブール値の「allowEvent」を追加することでした。次に、「allowEvent」を YES に設定する関数に UIControlEventTouchDown を接続しました。

UIControlEventTouchUpInside のセレクターで、allowEvent が YES かどうかを確認し、イベントを実行して allowEvent を NO に設定しました。

その後、イベントは 2 回発生しても 1 回だけ実行されます。

それが役に立てば幸い!

于 2009-08-20T21:49:49.430 に答える
1

皆さん、ありがとうございました。同じ問題があります。これは私のためにそれを解決するいくつかの整数数学です:

    static UInt32 counter = 0;

counter++;

if((counter/2)*2 != counter) return;
于 2010-01-05T22:52:56.960 に答える
0

このバグは 4.2 で修正されました。私は今、次のようにダンのコードを使用しています:

static UInt32 counter = 0;

if ([[UIDevice currentDevice].systemVersion compare: @"4.2" options: NSNumericSearch] == NSOrderedAscending) {
    counter++;
    if((counter/2)*2 != counter) return;
}
于 2010-10-25T09:48:34.943 に答える
0

私の以前のコメントはあまり受け入れられなかったので、誰かが興味を持っている場合に備えて、この問題の簡単な回避策を考え出すことにしました。

これが世界で最も効率的なソリューションではないことはわかっていますが、同じように機能します。

それぞれ TouchUp と ValueChanged にリンクされた、sliderUp と SliderChanged の 2 つのメソッドを作成しました。また、最初にゼロに設定されたグローバル int 変数 (必要に応じて timesFired) を作成しました。

SliderUp メソッドには、2 回実行してもかまわないコードを入れました。私の場合、スライダーが上にない場合は、スライダーを下に戻します(スライドのロック解除機能など)。また、遅延後に timesFired をゼロにリセットしました。他のメソッドを呼び出せるようにします。念のため。(performSelector: withObject: afterDelay: 方法がわからない場合)

sliderChanged メソッドでは、最初に if ステートメントを作成します: if(timesFired < 1) { } (スライダーを最大にするための if ステートメントも作成します)。 、スライダーが最大値に達したとき。そのコードが 1 回だけ起動されるようにするために、timesFired もインクリメントします。

ユーザーが timesFired で指を離すとすぐにゼロに設定され、プロセス全体が新たに開始されます。

さて、スライダーが一番上に達した後にスライダーをフリーズする方法を見つけたらすぐに、私は実際にこの解決策に満足しています. (単に無効にするだけで機能しますか?)

于 2009-07-25T22:59:14.593 に答える
0

試してみましたが、同じ動作に気付きました。最初は UISlider の endTrackingWithTouch:withEvent: メソッド (UIControl の touchesEnded:withEvent: メソッドによって呼び出される) から、次に同じ UIControl の touchesEnded:withEvent: メソッド (最初に endTrakingWithTouch:withEvent: メソッドを呼び出す) から呼び出されます。 .

また、タッチがスライダーの外で終了した場合、メソッドは endTrackingWithTouch:withEvent: メソッドによって 1 回だけ呼び出されます。touchesEnded:withEvent: メソッドはこれを呼び出しますが、コントロール内でタッチが終了したときのようにコールバックを呼び出しません。

それにしても、なぜ Touch Up Inside を接続するのでしょうか。ユーザーがいつコントロールに触れ始めたのか知りたいですか? Touch Up Inside の代わりに Touch Down を接続する必要があると思います。

編集:変更された値が必要であり、変更された値が頻繁に呼び出されます。テストを再実行したところ、次のことに気付きました。変更された値は、内部呼び出しの 2 つのタッチアップの間に呼び出されます。多分あなたはそれで何かをすることができますか?

于 2009-07-01T08:17:43.420 に答える
-1

Apple が将来この機能 (?) を修正しても壊れない単純な解決策は、最後の対話からの時間を格納するプロパティを追加することです。最後の対話から非常に短い時間である場合は終了します。

(以下のコードの latestTimeMark は、最初は viewDidLoad で現在の時刻に設定されています)

NSDate *now = [NSDate date];
 double nowDouble = [now timeIntervalSince1970];
 double difference = nowDouble - self.latestTimeMark;
 self.latestTimeMark = nowDouble;
 //NSLog(@"difference is now: %f", difference);
 if(difference<0.01f) return;
于 2010-05-26T16:22:44.967 に答える