UIControlEventTouchDragOutside实现的问题

时间:2013-05-04 17:05:54

标签: ios objective-c uitouch uicontrol uicontrolevents

我的主视图中有一个2维按钮数组,希望能够通过在此视图中拖动来移动它们。按钮很窄,大约23x23像素。我添加了控制事件touchDragExittouchDragOutside的目标,但是在我将手指移到按钮之外后,它们被解雇了很多像素。因此,我使用在SO中找到的一些代码对UIButton进行了子类化并覆盖了continueTrackingWithTouch。注意我没有调用超类实现。

-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGFloat boundsExtension = 5.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)
        {
            [self sendActionsForControlEvents:UIControlEventTouchDragExit];
        }
        else
        {
            [self sendActionsForControlEvents:UIControlEventTouchDragOutside];
        }
    }
    return self.tracking;
}

两个事件都被正确触发,但我的UIControlEventTouchDragOutside操作在调用其操作时收到错误的触摸信息。以下是我实施的第一部分:

-(void) dragOutside:(UIButton *) sender withEvents:(UIEvent *) event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint relativeLocToInitialCell = [touch locationInView:sender];

    NSLog(@"Translation %f %f NumTouch %d",relativeLocToInitialCell.x, relativeLocToInitialCell.y, [[event allTouches] count]);
    ...   
}

[[event allTouches] count]仍然返回0,直到我的手指远离按钮。当然,relativeLocToInitialCell字段xy都是0,这是我用于以后计算的值。知道可能是什么问题吗?

编辑:删除的答案建议使用UIPanGestureRecognizer而不是touchdrag事件,但我无法使用它,因为它在处理一个事件之前触发得太快我得到另一个事件。

1 个答案:

答案 0 :(得分:3)

我最终还要处理UIControlEventTouchDragInside事件。虽然这看起来是一种解决方法,但考虑这些触摸拖动事件的基本原理使其成为一种合理的解决方案。所有拖动事件均来自touchesBegan, touchesMoved and touchesEnded。 Apple在发送UIControlEventTouchDragOutside之前添加了一些阈值,但直到发送阈值UIControlEventTouchDragInside事件为止。

我的解决方案是删除重写的continueTrackingWithTouch方法并继续其默认实现。然后我处理了内部和外部事件,并将我的初始化代码从exit事件移动到inside事件,并在inside事件中添加了控制语句。抽象代码如下所示:

-(void) dragInside:(UIButton *) sender withEvents:(UIEvent *) event
{
    if(stillInsideOriginalControl) return;

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint relativeLocToInitialCell = [touch locationInView:sender];

    [self processTouch];
}

-(void) dragOutside:(UIButton *) sender withEvents:(UIEvent *) event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint relativeLocToInitialCell = [touch locationInView:sender];

    [self processTouch];
}