好吧,我想最好表明我的意思:
您可以清楚地看到,一旦我们触摸按钮并移出它,随后的移入事件会触发从远处按钮状态的变化.
虽然这种行为对于所有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]; }
注意:没有必要在最后返回方法的超级,但我把它留在那里是为了完整.