微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – UIButton触控拖动/退出命中区的大小是多少?

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

您可以清楚地看到,一旦我们触摸按钮并移出它,随后的移入事件会触发从远处按钮状态的变化.

虽然这种行为对于所有UIButton都很自然,但我无法谷歌解决方案来改变它.

有没有办法减少这种类型的UIButton灵敏度的命中区域?我希望它减少,因为我觉得按钮足够大,它将提供更好的用户体验以及上/下音效.

UPD:UIButton的以下覆盖代码发布于another thread

- (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];
}

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

解决方法

我不知道你是否还有同样的问题,但我能够通过在touchesEnded:withEvent:方法中使用类似的代码来修复它.

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

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

- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGFloat boundsExtension = 25.0f;
    CGRect outerBounds = CGRectInset(self.bounds,[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);

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

注意:没有必要在最后返回方法的超级,但我把它留在那里是为了完整.

原文地址:https://www.jb51.cc/iOS/333623.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐