Well, I guess it is best to show what I mean:
You can clearly see that once we've touched the button and moved out of it, a consequent move-in event triggers the button state change from far away.
While this behavior is natural for all UIButtons, I couldn't google a solution to alter it.
Is there a way to reduce the hit area for this type of UIButton sensitivity? I want it reduced, because I feel that the button is large enough as it is, and it will provide a better user experience along with up/down sound effects.
UPD: The following override code for UIButton was posted in 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];
}
It alters the hit area extension used by Drag In/Drag Out events, yet button Up/Down states switch exactly the same way as they did before.
A Swift version:
private let _boundsExtension: CGFloat = 0 // Adjust this as needed
override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool {
let outerBounds: CGRect = CGRectInset(bounds, -1 * _boundsExtension, -1 * _boundsExtension)
let currentLocation: CGPoint = touch.locationInView(self)
let previousLocation: CGPoint = touch.previousLocationInView(self)
let touchOutside: Bool = !CGRectContainsPoint(outerBounds, currentLocation)
if touchOutside {
let previousTouchInside: Bool = CGRectContainsPoint(outerBounds, previousLocation)
if previousTouchInside {
sendActionsForControlEvents(.TouchDragExit)
} else {
sendActionsForControlEvents(.TouchDragOutside)
}
} else {
let previousTouchOutside: Bool = !CGRectContainsPoint(outerBounds, previousLocation)
if previousTouchOutside {
sendActionsForControlEvents(.TouchDragEnter)
} else {
sendActionsForControlEvents(.TouchDragInside)
}
}
return true
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch: UITouch = touches.first!
let outerBounds: CGRect = CGRectInset(bounds, -1 * _boundsExtension, -1 * _boundsExtension)
let currentLocation: CGPoint = touch.locationInView(self)
let touchInside: Bool = CGRectContainsPoint(outerBounds, currentLocation)
if touchInside {
return sendActionsForControlEvents(.TouchUpInside)
} else {
return sendActionsForControlEvents(.TouchUpOutside)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With