7

現時点ではUIControlEventTouchDragExit、ボタンから 100 ピクセル離れた場所にドラッグしたときにのみトリガーされます。この動作をカスタマイズして、その範囲を約 25 ピクセルにしたいと考えていますが、プログラミングに比較的慣れていないため、このような組み込みメソッドをオーバーライド/カスタマイズする必要はありませんでした。

ここの他の投稿で、UIButton(またはおそらくUIControl?)、オーバーライド-(BOOL) beginTrackingWithTouch: (UITouch *) touch withEvent: (UIEvent *) event、および関連するメソッドをサブクラス化する必要があることを読みましたが、どこから始めればよいかわかりません。

どうすればこれを達成できるかについて、誰か親切にアドバイスをいただけますか? とても有難い!^_^

4

3 に答える 3

11

continueTrackingWithTouch:withEvent: を次のようにオーバーライドして、デフォルトのガター内で DragExit/DragOutside イベントを送信します。

- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGFloat boundsExtension = 25.0f;
    CGRect outerBounds = CGRectInset(self.bounds, -1 * boundsExtension, -1 * boundsExtension);

    BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:self]);
    if(touchOutside)
    {
        BOOL previousTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:self]);
        if(previousTouchInside)
        {
            NSLog(@"Sending UIControlEventTouchDragExit");
            [self sendActionsForControlEvents:UIControlEventTouchDragExit];
        }
        else
        {
            NSLog(@"Sending UIControlEventTouchDragOutside");
            [self sendActionsForControlEvents:UIControlEventTouchDragOutside];
        }
    }
    return [super continueTrackingWithTouch:touch withEvent:event];
}
于 2013-01-18T13:33:17.490 に答える
7

受け入れられた回答には2つの問題があることがわかりました。

  1. 登録されたアクションは 2 回呼び出されます:
    • 1 回目は、上書きされた方法で設定されている 25 ピクセルのコントロールから指が離れたときです。
    • 2 回目は、指がコントロールから約 70 ピクセル離れたときに呼び出されます。これは、UIControl のデフォルトの動作です。
  2. event2 番目の問題は、パラメータから取得した位置が であり(0, 0)、正しく初期化されていないことです。

この回答に基づいて、この目的を達成する別の方法を見つけました。基本的な考え方は、そのメソッドを上書きするのではなく、コールバックでイベントを処理することです。次の 2 つの手順があります。

アクションを登録します。

    // to get the touch up event
    [btn addTarget:self action:@selector(btnTouchUp:withEvent:) forControlEvents:UIControlEventTouchUpInside];
    [btn addTarget:self action:@selector(btnTouchUp:withEvent:) forControlEvents:UIControlEventTouchUpOutside];
    // to get the drag event
    [btn addTarget:self action:@selector(btnDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside];
    [btn addTarget:self action:@selector(btnDragged:withEvent:) forControlEvents:UIControlEventTouchDragOutside];

イベントを処理します。

- (void)btnTouchUp:(UIButton *)sender withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGFloat boundsExtension = 25.0f;
    CGRect outerBounds = CGRectInset(sender.bounds, -1 * boundsExtension, -1 * boundsExtension);
    BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:sender]);
    if (touchOutside) {
        // UIControlEventTouchUpOutside
    } else {
        // UIControlEventTouchUpInside
    }
}

- (void)btnDragged:(UIButton *)sender withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGFloat boundsExtension = 25.0f;
    CGRect outerBounds = CGRectInset(sender.bounds, -1 * boundsExtension, -1 * boundsExtension);
    BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:sender]);
    if (touchOutside) {
        BOOL previewTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:sender]);
        if (previewTouchInside) {
            // UIControlEventTouchDragExit
        } else {
            // UIControlEventTouchDragOutside
        }
    } else {
        BOOL previewTouchOutside = !CGRectContainsPoint(outerBounds, [touch previousLocationInView:sender]);
        if (previewTouchOutside) {
            // UIControlEventTouchDragEnter
        } else {
            // UIControlEventTouchDragInside
        }
    }    
}

これで、6 つのイベントすべてを25ピクセルの境界拡張で処理できるようになりました。もちろん、この値を必要に応じて他の値に設定することもできます。

于 2015-05-19T08:17:44.900 に答える
1

私がここで読んだことによると

Apple は、指を使用することによる不正確さを考慮して 100 ピクセルとしています。以下を使用してメソッドをオーバーライドできます。

  • -(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
  • -(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

およびその他のメソッドに関連するメソッド。アップルのドキュメント

于 2013-01-15T21:03:02.350 に答える