UIControlEventTouchDragExit triggers when 100 pixels away from UIButton
Override continueTrackingWithTouch:withEvent: like this to send DragExit/DragOutside events inside of the default gutter:
- (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];
}
UIControlEventTouchDragExit only fires ~100 pixels out
The extra area is a built-in feature, to account for the inexactness of using a finger to interact with the interface. If you want to get around this, you have to subclass UIControl and override -(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
and related methods to get the behavior your want.
What's up with the size of UIButton's Touch Drag/Exit hit area?
I don't know if you are still having the same issue, but I was able to fix it by using similar code in the touchesEnded:withEvent: method.
I also changed that method to add touchEnter and dragInside because with the current code, those to events still used the same bounds. In addition I made each of the cases return YES so that the super is not called (it would cause the touch drag inside to be called prematurely).
Here is the final code that I ended up with, in two methods:
- (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];
}
NOTE: Returning the super of the method at the end is not necessary, but I left it in there for completeness.
Correct function signature for UIButton action messages in Swift
You need to change the selector your use when setting up the button:
button.addTarget(self, action: "buttonTouchUp:event:",
forControlEvents: .TouchUpInside)
func buttonTouchUp(sender: UIButton!,
event: UIEvent) {
(The action signature follows the Cbjective-C syntax, where you just list the parameters followed by colons.)
VS2008 C++ Compiler error?
The first compiles because the assignment operator is called what has one signature of "string& operator= ( char c )" and the compiler can convert 1 into a char.
The second won't compile because it calls the copy constructor which has no compatible signature.
Related Topics
Can't Load Uiviewcontroller Xib File in Storyboard in Swift
Differencebetween Int and Int32 in Swift
Corebluetooth: What Is the Lifetime of Unique Uuids
Getting Data from Each Uitableview Cells Swift
Uiimagejpegrepresentation Received Memory Warning
Fetching Selected Attribute in Entities
Enable and Debug Zombie Objects in iOS Using Xcode 5.1.1
How to Use Local-Only Project via Cocoapods
Cabasicanimation Resets to Initial Value After Animation Completes
Xctest/Xctest.H Not Found on Old Projects Built in Xcode 6
Codesign Returned Unknown Error -1=Ffffffffffffffff
Uitextview Is Not Scrolled to Top When Loaded
Avfoundation Image Orientation Off by 90 Degrees in the Preview But Fine in Camera Roll
Get Dns Server Ip from iPhone Settings
How to Display the Emoji and Special Characters in Uilabel and Uitextviews
Spritekit: Why Does It Wait One Round for the Score to Update? (Swift)
Swift 3 JSON Nsfastenumerationiterator Has No Subscript Members