UIControlEventTouchDragExit在距离UIButton 100像素时触发

目前, UIControlEventTouchDragExit只会在我从button拖动100个像素的时候触发。 我想定制这种行为,并把这个范围在25像素左右,但我相对较新的编程,并从来没有需要重写/定制这样的内置方法。

我已经读过一些其他post,我需要UIButton (或者甚至UIControl ?),并覆盖-(BOOL) beginTrackingWithTouch: (UITouch *) touch withEvent: (UIEvent *) event和相关的方法,但我真的不知道从哪里开始这样做。

任何人都可以提供一些build议,我可以做到这一点? 非常感激! ^ _ ^

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

我发现接受的答案有两个问题。

  1. 注册的操作将被调用两次:
    • 第一次是手指离开控制的25个像素,这是在覆盖的方法中设置的。
    • 当手指离开控制大约70个像素时,第二次被调用,这是UIControl的默认行为。
  2. 第二个问题是从event参数检索的位置是(0, 0) ,它没有正确初始化。

我发现另一种方法来完成这个目的的基础上这个答案,基本的想法是在callback中处理事件,而不是覆盖该方法。 有两个步骤:

注册操作:

  // 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 } } } 

现在所有的六个事件都可以用25像素的范围扩展来处理,当然你可以根据需要设置这个值。

根据我在这里读到的

苹果公司提出100个像素来解释使用手指的不准确性。 您可以使用以下方法覆盖方法:

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

和其他方法相关的方法。 Apple文档 。

Interesting Posts