[ios] fix pressable with intercepting detector#4041
[ios] fix pressable with intercepting detector#4041akwasniewski wants to merge 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes iOS Pressable activation when an InterceptingGestureDetector under the pressable causes touches to land on nested text views, preventing the outer button from receiving the expected control events.
Changes:
- Added
touchesBegan/Ended/Cancelledoverrides on iOS to dispatchUIControlactions when the touch originates from a subview rather than the button itself.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [super touchesEnded:touches withEvent:event]; | ||
| UITouch *touch = [touches anyObject]; | ||
| if (touch.view != self) { | ||
| [self sendActionsForControlEvents:UIControlEventTouchUpInside]; |
There was a problem hiding this comment.
touchesEnded unconditionally sends UIControlEventTouchUpInside whenever the touch began on a subview (touch.view != self). This can fire the press action even when the finger is released outside the control bounds (drag-out cancellation), which breaks expected Pressable/UIControl semantics. Consider checking the touch end location against pointInside:withEvent: (respecting hitTestEdgeInsets) and sending UIControlEventTouchUpInside only when inside; otherwise send UIControlEventTouchUpOutside (or cancel as appropriate).
| [self sendActionsForControlEvents:UIControlEventTouchUpInside]; | |
| CGPoint location = [touch locationInView:self]; | |
| if ([self pointInside:location withEvent:event]) { | |
| [self sendActionsForControlEvents:UIControlEventTouchUpInside]; | |
| } else { | |
| [self sendActionsForControlEvents:UIControlEventTouchUpOutside]; | |
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event | ||
| { | ||
| [super touchesBegan:touches withEvent:event]; | ||
| UITouch *touch = [touches anyObject]; | ||
| if (touch.view != self) { | ||
| [self sendActionsForControlEvents:UIControlEventTouchDown]; | ||
| } | ||
| } | ||
|
|
||
| - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event | ||
| { | ||
| [super touchesEnded:touches withEvent:event]; | ||
| UITouch *touch = [touches anyObject]; | ||
| if (touch.view != self) { | ||
| [self sendActionsForControlEvents:UIControlEventTouchUpInside]; | ||
| } | ||
| } |
There was a problem hiding this comment.
In the touch.view != self path the control manually emits only TouchDown, TouchUpInside, and TouchCancel, but never emits drag-related events (TouchDragExit/TouchDragEnter/TouchDragOutside) or TouchUpOutside. Since commonInit wires handleAnimatePressOut to TouchDragExit/TouchUpOutside, this can cause pressed visuals/state to behave differently when the finger moves outside the control before ending. Consider implementing touchesMoved: to mirror UIControl’s inside/outside tracking and emit the corresponding control events (or otherwise ensure press-out is dispatched when the touch leaves bounds).
Description
On ios when under pressable we had an intercepting detector handling a nested text gesture, pressable did not activate when we pressed on the part of the text with no virtual gesture attached to it. This PR should fix the issue.
Note: on web the nested text gesture never activates when under a pressable, web needs further care.
Test plan
Tested on the following example
Details