From dd6cb118eadb5934bad956a0a60e285e75f616f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 22 Oct 2026 16:34:20 +0200 Subject: [PATCH 1/2] Fix missing onPressOut --- .../src/v3/components/StatefulPressable.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx b/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx index bfbf25608e..99bdb2b80f 100644 --- a/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx @@ -91,6 +91,7 @@ const StatefulPressable = (props: PressableProps) => { const isOnPressAllowed = useRef(true); const jsResponderContext = use(JSResponderContext); const isCurrentlyPressed = useRef(false); + const pressInEventRef = useRef(null); const dimensions = useRef({ width: 0, height: 0, @@ -304,6 +305,7 @@ const StatefulPressable = (props: PressableProps) => { } const pressableEvent = gestureTouchToPressableEvent(event); + pressInEventRef.current = pressableEvent; stateMachine.handleEvent( StateMachineEvent.LONG_PRESS_TOUCHES_DOWN, pressableEvent @@ -400,6 +402,21 @@ const StatefulPressable = (props: PressableProps) => { event.canceled ? StateMachineEvent.CANCEL : StateMachineEvent.FINALIZE ); + // On iOS the button's cancel can land before the long press's touch + // cancel, or without one, so deliver the press-out here + if ( + Platform.OS === 'ios' && + event.canceled && + isCurrentlyPressed.current + ) { + handlePressOut( + pressInEventRef.current ?? + viewCenterToPressableEvent(dimensions.current), + false + ); + return; + } + handleFinalize(); }, enabled: disabled !== true, From 847c38d79e8937b8dcaca27f0d3a60f9ef9b1387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 26 Oct 2026 10:44:27 +0100 Subject: [PATCH 2/2] Move event ref to onPressIn --- .../src/v3/components/StatefulPressable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx b/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx index 99bdb2b80f..e34332e5ae 100644 --- a/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/StatefulPressable.tsx @@ -188,6 +188,7 @@ const StatefulPressable = (props: PressableProps) => { } isCurrentlyPressed.current = true; + pressInEventRef.current = event; if (unstable_pressDelay) { pressDelayTimeoutRef.current = setTimeout(() => { innerHandlePressIn(event); @@ -305,7 +306,6 @@ const StatefulPressable = (props: PressableProps) => { } const pressableEvent = gestureTouchToPressableEvent(event); - pressInEventRef.current = pressableEvent; stateMachine.handleEvent( StateMachineEvent.LONG_PRESS_TOUCHES_DOWN, pressableEvent