9

さて、私が言いたいことを示すのが最善だと思います:

ドラッグ モーションに反応する UIButton のアニメーション

ボタンに触れてそこから移動すると、その結果の移動イベントがボタンの状態の変化を遠くからトリガーすることがはっきりとわかります。

この動作はすべての UIButton で自然ですが、それを変更するための解決策をグーグルで検索することはできませんでした。

このタイプの UIButton 感度のヒット領域を減らす方法はありますか? ボタンはそのままで十分大きく、上下の効果音とともにユーザーエクスペリエンスが向上すると思うので、減らしてほしいです。

UPD: UIButton の次のオーバーライド コードが別のスレッドに投稿されました。

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

Drag In/Drag Out イベントで使用されるヒット領域の拡張を変更しますが、ボタンの Up/Down 状態は以前とまったく同じように切り替わります。

4

2 に答える 2

2

Swift バージョン:

  private let _boundsExtension: CGFloat = 0 // Adjust this as needed

  override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool {
    let outerBounds: CGRect = CGRectInset(bounds, -1 * _boundsExtension, -1 * _boundsExtension)
    let currentLocation: CGPoint = touch.locationInView(self)
    let previousLocation: CGPoint = touch.previousLocationInView(self)

    let touchOutside: Bool = !CGRectContainsPoint(outerBounds, currentLocation)
    if touchOutside {
      let previousTouchInside: Bool = CGRectContainsPoint(outerBounds, previousLocation)
      if previousTouchInside {
        sendActionsForControlEvents(.TouchDragExit)
      } else {
        sendActionsForControlEvents(.TouchDragOutside)
      }
    } else {
      let previousTouchOutside: Bool = !CGRectContainsPoint(outerBounds, previousLocation)
      if previousTouchOutside {
        sendActionsForControlEvents(.TouchDragEnter)
      } else {
        sendActionsForControlEvents(.TouchDragInside)
      }
    }

    return true
  }

  override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let touch: UITouch = touches.first!
    let outerBounds: CGRect = CGRectInset(bounds, -1 * _boundsExtension, -1 * _boundsExtension)
    let currentLocation: CGPoint = touch.locationInView(self)

    let touchInside: Bool = CGRectContainsPoint(outerBounds, currentLocation)
    if touchInside {
      return sendActionsForControlEvents(.TouchUpInside)
    } else {
      return sendActionsForControlEvents(.TouchUpOutside)
    }
  }
于 2016-07-12T17:53:15.400 に答える