UIButton触控拖动/退出命中区的大小有多大?

Kai*_*Kai 9 cocoa-touch button touch uibutton ios

好吧,我想最好表明我的意思:

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];
}
Run Code Online (Sandbox Code Playgroud)

它改变了拖入/拖出事件使用的命中区域扩展,但按钮向上/向下状态切换的方式与之前完全相同.

Jsd*_*ers 1

我不知道您是否仍然遇到同样的问题,但我能够通过在 TouchesEnded:withEvent: 方法中使用类似的代码来修复它。

我还更改了该方法以添加 touchEnter 和 DragInside,因为在当前代码中,这些事件仍然使用相同的边界。另外,我让每个案例都返回 YES,这样 super 就不会被调用(这会导致内部的触摸拖动被过早调用)。

这是我最终得到的代码,有两种方法:

- (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) {
            [self sendActionsForControlEvents:UIControlEventTouchDragExit];
            return YES;
        }
        else
        {
            [self sendActionsForControlEvents:UIControlEventTouchDragOutside];
            return YES;
        }
    }
    else {
        BOOL previousTouchOutside = !CGRectContainsPoint(outerBounds, [touch previousLocationInView:self]);
        if (previousTouchOutside) {
            [self sendActionsForControlEvents:UIControlEventTouchDragEnter];
            return YES;
        }
        else {
            [self sendActionsForControlEvents:UIControlEventTouchDragInside];
            return YES;
        }
    }
    return [super continueTrackingWithTouch:touch withEvent:event];
}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGFloat boundsExtension = 25.0f;
    CGRect outerBounds = CGRectInset(self.bounds, -1 * boundsExtension, -1 * boundsExtension);

    BOOL touchInside = CGRectContainsPoint(outerBounds, [touch locationInView:self]);
    if (touchInside) {
        return [self sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
    else {
        return [self sendActionsForControlEvents:UIControlEventTouchUpOutside];
    }
    return [super endTrackingWithTouch:touch withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)

注意:最后返回方法的 super 是不必要的,但为了完整性我将其留在那里。