UIControlEventTouchDragExit触发时从UIButton的100个像素离开(U

2019-07-18 06:25发布

目前, UIControlEventTouchDragExit当我拖动从按钮100个像素仅有触发器。 我想定制这一行为,并把该范围中约25像素,但我是比较新的节目,从来没有要重写/定制这样一个内置的方法。

我在这里的一些其他职位看,我会需要继承UIButton (甚至UIControl ?),并覆盖-(BOOL) beginTrackingWithTouch: (UITouch *) touch withEvent: (UIEvent *) event和相关方法,但我真的不知道从哪里开始这样做。

谁能好心提供一些建议,我怎么可能做到这一点? 非常感激! ^ _ ^

Answer 1:

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


Answer 2:

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

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

我找到了另一种方式来实现基于这样的回答这个目的,其基本思想是在回调来处理该事件,而不是覆盖该方法。 有两个步骤:

注册操作:

    // 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像素,可以当然这个值,你想设置为其他。



Answer 3:

据我看这里

苹果提出100个像素账户用手指的不准确性。 您可以在此改变使用方法:

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

等方法相关的方法。 苹果文档 。



文章来源: UIControlEventTouchDragExit triggers when 100 pixels away from UIButton