1

これらの質問が何度も出てきたことは知っていNSTimerますが、UI を変更するブロックの実行を伴うものはないように見えるので、これはまだオリジナルの質問であると考えました。

私はそのサブクラスを持っています。UIButton便宜上(Androidバックグラウンドから来た私)にはonClickandonHoldClick関数があります。onClickは単にブロックを取り、に応答するセレクターでそれを実行しUIControlEventTouchUpInsideます。クリック機能が大活躍。例えば:

[myButton setOnClick:^{
    NSLog(@"clicked");
}];

ホールド クリック機能がうまく機能していません。

[myButton setOnHoldClick:^{
    NSLog(@"still holding click...");
}];

UIControlEventTouchDownこれはイベントをリッスンし、遅延後にタスクを実行します。

- (void)clickDown:(id)sender
{
    isClicked = YES;

    [self performSelector:@selector(holdLoop:) withObject:nil afterDelay:delay];//For the sake of the example, delay is set to 0.5  
}

ホールド ループは、ブロックの実行を処理する別の関数で繰り返しタイマーを実行します (タイマー変数はNSTimerヘッダー ファイルで宣言されています)。

-(void)holdLoop:(id)sender
{
    [self cancelTimers];
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(death:) userInfo:nil repeats:YES];
}

-(void)death:(id)_delay
{

    if (isClicked)
    {
        _holdBlock();
    }
    else
    {
        [self cancelTimers];

    }
}

実行するブロックは、再描画されるラベルの値を更新するために使用される float の値を変更します。

ホールド クリック イベントが初めて発生したとき、これはうまく機能します。その後、タイマーがキャンセルされないようで、新しいタイマーが追加され続けています。これは私のcancelTimers関数がどのように見えるかです (ここでの呼び出しは、このトピックに関する他の質問のコレクションから取得されます):

-(void)cancelTimers
{
    [_timer invalidate];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(death:) object:nil];
}

私は何を間違っていますか、どうすれば修正できますか?

編集

実際、私はすでにタッチアップに応答する関数を内部に持っています:

- (void)clickUp:(id)sender
{
    isClicked = NO;
    [self cancelTimers];
    _clickBlock();
}

さらに、この問題は未処理のキャンセル イベントが原因であることに気付きました。iOS が長押しを自動キャンセルする理由はありますか?

4

2 に答える 2

2

解決済み

ブロックが UI を再描画したため、ボタンも再描画されました (そして、その機能がリセットされました)。このイベントにより、ボタンでキャンセル イベントが呼び出されていましたが、これは処理されませんでした。以下を追加します。

[self addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchCancel];
[self addTarget:self action:@selector(cancelClick:) forControlEvents:UIControlEventTouchUpOutside];


-(void)cancelClick:(id)sender
{
    isClicked = NO;
    [self cancelTimers];
}

ブロックに加えられた変更を再考するだけでなく、この問題を乗り越えることができました。

于 2013-06-04T15:33:49.353 に答える
1

コメントとコードから理解したように、最初にボタンがタッチされたときにclickDown:呼び出されるUIControlEventTouchDownので、isClickedに設定されます。YESイベントにセレクターを追加する必要がありますUIControlEventTouchUpInside。ユーザーがボタンの境界の外にいるときに指を離すと呼び出されます。そのメソッド内で、に設定isClickedNOます。

于 2013-06-04T15:18:41.433 に答える