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]; }
我发现接受的答案有两个问题。
- 注册的操作将被调用两次:
- 第一次是手指离开控制的25个像素,这是在覆盖的方法中设置的。
- 当手指离开控制大约70个像素时,第二次被调用,这是UIControl的默认行为。
- 第二个问题是从
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文档 。