From eace4ec481dbe8d8149d0eef165650c308f460f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 23 Mar 2026 10:01:36 +0100 Subject: [PATCH 01/13] Fix callbacks on iOS native side --- .../apple/Handlers/RNNativeViewHandler.mm | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm index dd9251c267..f4956d2826 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm +++ b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm @@ -146,6 +146,12 @@ - (void)bindToView:(UIView *)view action:@selector(handleTouchUpInside:forEvent:) forControlEvents:UIControlEventTouchUpInside]; [control addTarget:self action:@selector(handleDragExit:forEvent:) forControlEvents:UIControlEventTouchDragExit]; + [control addTarget:self + action:@selector(handleDragInside:forEvent:) + forControlEvents:UIControlEventTouchDragInside]; + [control addTarget:self + action:@selector(handleDragOutside:forEvent:) + forControlEvents:UIControlEventTouchDragOutside]; [control addTarget:self action:@selector(handleDragEnter:forEvent:) forControlEvents:UIControlEventTouchDragEnter]; [control addTarget:self action:@selector(handleTouchCancel:forEvent:) forControlEvents:UIControlEventTouchCancel]; } else { @@ -184,7 +190,7 @@ - (void)handleTouchDown:(UIView *)sender forEvent:(UIEvent *)event } } - [self sendEventsInState:RNGestureHandlerStateActive + [self sendEventsInState:RNGestureHandlerStateBegan forViewWithTag:sender.reactTag withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withNumberOfTouches:event.allTouches.count @@ -238,6 +244,24 @@ - (void)handleDragEnter:(UIView *)sender forEvent:(UIEvent *)event withPointerType:_pointerType]]; } +- (void)handleDragInside:(UIView *)sender forEvent:(UIEvent *)event +{ + [self sendEventsInState:RNGestureHandlerStateActive + forViewWithTag:sender.reactTag + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; +} + +- (void)handleDragOutside:(UIView *)sender forEvent:(UIEvent *)event +{ + [self sendEventsInState:RNGestureHandlerStateActive + forViewWithTag:sender.reactTag + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; +} + - (void)handleTouchCancel:(UIView *)sender forEvent:(UIEvent *)event { [self sendEventsInState:RNGestureHandlerStateCancelled From 75666db0628a44c37dd74f93e70d053623e4601a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 23 Mar 2026 10:02:46 +0100 Subject: [PATCH 02/13] Simplify button --- .../src/v3/components/GestureButtons.tsx | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx index 961e10a06c..d530f35b90 100644 --- a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx @@ -34,28 +34,17 @@ export const BaseButton = (props: BaseButtonProps) => { }; const onBegin = (e: CallbackEventType) => { - if (Platform.OS === 'android' && e.pointerInside) { - longPressDetected.current = false; - if (onLongPress) { - longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress); - } - - props.onBegin?.(e); + longPressDetected.current = false; + if (onLongPress) { + longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress); } + + props.onBegin?.(e); }; const onActivate = (e: CallbackEventType) => { onActiveStateChange?.(true); - if (Platform.OS !== 'android' && e.pointerInside) { - longPressDetected.current = false; - if (onLongPress) { - longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress); - } - - props.onBegin?.(e); - } - if (!e.pointerInside && longPressTimeout.current !== undefined) { clearTimeout(longPressTimeout.current); longPressTimeout.current = undefined; From 3f12e06ea8e059f61db48a2de5bae6b81a8c4f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 23 Mar 2026 10:04:13 +0100 Subject: [PATCH 03/13] Pressable --- .../src/components/Pressable/stateDefinitions.ts | 2 +- .../src/v3/components/Pressable.tsx | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/react-native-gesture-handler/src/components/Pressable/stateDefinitions.ts b/packages/react-native-gesture-handler/src/components/Pressable/stateDefinitions.ts index 55279211cd..5d9a5f7cf5 100644 --- a/packages/react-native-gesture-handler/src/components/Pressable/stateDefinitions.ts +++ b/packages/react-native-gesture-handler/src/components/Pressable/stateDefinitions.ts @@ -38,7 +38,7 @@ function getIosStatesConfig( eventName: StateMachineEvent.LONG_PRESS_TOUCHES_DOWN, }, { - eventName: StateMachineEvent.NATIVE_START, + eventName: StateMachineEvent.NATIVE_BEGIN, callback: handlePressIn, }, { diff --git a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx index 50d3ce15e5..2572fb44d5 100644 --- a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx @@ -302,8 +302,9 @@ const Pressable = (props: PressableProps) => { stateMachine.handleEvent(StateMachineEvent.NATIVE_BEGIN); }, onActivate: () => { - if (Platform.OS !== 'android') { + if (Platform.OS !== 'android' && Platform.OS !== 'ios') { // Native.onActivate is broken with Android + hitSlop + // On iOS, onActivate fires on drag (not touch down), so we use onBegin + LONG_PRESS_TOUCHES_DOWN instead stateMachine.handleEvent(StateMachineEvent.NATIVE_START); } }, @@ -317,9 +318,7 @@ const Pressable = (props: PressableProps) => { success ? StateMachineEvent.FINALIZE : StateMachineEvent.CANCEL ); - if (Platform.OS !== 'ios') { - handleFinalize(); - } + handleFinalize(); }, enabled: disabled !== true, disableReanimated: true, From 83b52ccb69205937b760405008b768a142830a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 23 Mar 2026 10:22:57 +0100 Subject: [PATCH 04/13] One send --- .../apple/Handlers/RNNativeViewHandler.mm | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm index f4956d2826..d680fb188d 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm +++ b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm @@ -217,22 +217,21 @@ - (void)handleTouchUpInside:(UIView *)sender forEvent:(UIEvent *)event - (void)handleDragExit:(UIView *)sender forEvent:(UIEvent *)event { + RNGestureHandlerState newState = RNGestureHandlerStateActive; + // Pointer is moved outside of the view bounds, we cancel button when `shouldCancelWhenOutside` is set if (self.shouldCancelWhenOutside) { UIControl *control = (UIControl *)sender; [control cancelTrackingWithEvent:event]; - [self sendEventsInState:RNGestureHandlerStateEnd - forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO - withNumberOfTouches:event.allTouches.count - withPointerType:_pointerType]]; - } else { - [self sendEventsInState:RNGestureHandlerStateActive - forViewWithTag:sender.reactTag - withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO - withNumberOfTouches:event.allTouches.count - withPointerType:_pointerType]]; + + newState = RNGestureHandlerStateEnd; } + + [self sendEventsInState:newState + forViewWithTag:sender.reactTag + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } - (void)handleDragEnter:(UIView *)sender forEvent:(UIEvent *)event From 71d5b2b198a837d1de148ceedd02fb9007e9d3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 23 Mar 2026 11:10:32 +0100 Subject: [PATCH 05/13] Old buttons --- .../src/components/GestureButtons.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/react-native-gesture-handler/src/components/GestureButtons.tsx b/packages/react-native-gesture-handler/src/components/GestureButtons.tsx index 43ed5518a6..d81c315a3e 100644 --- a/packages/react-native-gesture-handler/src/components/GestureButtons.tsx +++ b/packages/react-native-gesture-handler/src/components/GestureButtons.tsx @@ -62,12 +62,7 @@ class InnerBaseButton extends React.Component { this.props.onPress(pointerInside); } - if ( - !this.lastActive && - // NativeViewGestureHandler sends different events based on platform - state === (Platform.OS !== 'android' ? State.ACTIVE : State.BEGAN) && - pointerInside - ) { + if (!this.lastActive && state === State.BEGAN && pointerInside) { this.longPressDetected = false; if (this.props.onLongPress) { this.longPressTimeout = setTimeout( From c73ec16f8b7369f608b240b238d0f1313bdc186f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 23 Mar 2026 12:31:00 +0100 Subject: [PATCH 06/13] Fix active state handling for non-Android platforms in BaseButton --- .../src/v3/components/GestureButtons.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx index d530f35b90..0b165acb95 100644 --- a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx @@ -34,6 +34,11 @@ export const BaseButton = (props: BaseButtonProps) => { }; const onBegin = (e: CallbackEventType) => { + // iOS, macOS. Web has its own implementation of button. + if (Platform.OS !== 'android') { + onActiveStateChange?.(true); + } + longPressDetected.current = false; if (onLongPress) { longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress); @@ -43,7 +48,9 @@ export const BaseButton = (props: BaseButtonProps) => { }; const onActivate = (e: CallbackEventType) => { - onActiveStateChange?.(true); + if (Platform.OS === 'android') { + onActiveStateChange?.(true); + } if (!e.pointerInside && longPressTimeout.current !== undefined) { clearTimeout(longPressTimeout.current); From cb5849582be0220901fbaa42f80d8375af3b479b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 23 Mar 2026 17:17:42 +0100 Subject: [PATCH 07/13] Bring back pointerInside check --- .../src/v3/components/GestureButtons.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx index 480b0a5446..1dbea28a88 100644 --- a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx @@ -38,6 +38,10 @@ export const BaseButton = (props: BaseButtonProps) => { }; const onBegin = (e: CallbackEventType) => { + if (!e.pointerInside) { + return; + } + // iOS, macOS. Web has its own implementation of button. if (Platform.OS !== 'android') { onActiveStateChange?.(true); @@ -52,7 +56,7 @@ export const BaseButton = (props: BaseButtonProps) => { }; const onActivate = (e: CallbackEventType) => { - if (Platform.OS === 'android') { + if (Platform.OS === 'android' && e.pointerInside) { onActiveStateChange?.(true); } From ad05004f6f63f6c333921d92e7028fbdca26b58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 25 Mar 2026 13:27:28 +0100 Subject: [PATCH 08/13] Unify buttons across platforms --- .../gesturehandler/core/NativeViewGestureHandler.kt | 10 ++++------ .../apple/Handlers/RNNativeViewHandler.mm | 6 ++++++ .../src/v3/components/GestureButtons.tsx | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt index 4800c5aa1a..a254d9ac63 100644 --- a/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt +++ b/packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt @@ -123,6 +123,10 @@ class NativeViewGestureHandler : GestureHandler() { hook.afterGestureEnd(event) } else if (state == STATE_UNDETERMINED || state == STATE_BEGAN) { + if (state != STATE_BEGAN && hook.canBegin(event)) { + begin() + } + when { shouldActivateOnStart -> { tryIntercept(view, event) @@ -138,12 +142,6 @@ class NativeViewGestureHandler : GestureHandler() { hook.wantsToHandleEventBeforeActivation() -> { hook.handleEventBeforeActivation(event) } - - state != STATE_BEGAN -> { - if (hook.canBegin(event)) { - begin() - } - } } } else if (state == STATE_ACTIVE) { hook.sendTouchEvent(view, event) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm index d680fb188d..7005d3db2a 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm +++ b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm @@ -195,6 +195,12 @@ - (void)handleTouchDown:(UIView *)sender forEvent:(UIEvent *)event withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES withNumberOfTouches:event.allTouches.count withPointerType:_pointerType]]; + + [self sendEventsInState:RNGestureHandlerStateActive + forViewWithTag:sender.reactTag + withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES + withNumberOfTouches:event.allTouches.count + withPointerType:_pointerType]]; } - (void)handleTouchUpOutside:(UIView *)sender forEvent:(UIEvent *)event diff --git a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx index 1dbea28a88..381dff8f9f 100644 --- a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx @@ -19,7 +19,7 @@ export const RawButton = createNativeWrapper< RawButtonProps >(GestureHandlerButton, { shouldCancelWhenOutside: false, - shouldActivateOnStart: false, + shouldActivateOnStart: true, }); export const BaseButton = (props: BaseButtonProps) => { From cdd6619223805704afa8fa790bfa380817769608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 25 Mar 2026 13:32:51 +0100 Subject: [PATCH 09/13] Remove platform checks --- .../src/v3/components/GestureButtons.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx index 381dff8f9f..cec9b8cf10 100644 --- a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx @@ -42,10 +42,7 @@ export const BaseButton = (props: BaseButtonProps) => { return; } - // iOS, macOS. Web has its own implementation of button. - if (Platform.OS !== 'android') { - onActiveStateChange?.(true); - } + onActiveStateChange?.(true); longPressDetected.current = false; if (onLongPress) { @@ -56,10 +53,6 @@ export const BaseButton = (props: BaseButtonProps) => { }; const onActivate = (e: CallbackEventType) => { - if (Platform.OS === 'android' && e.pointerInside) { - onActiveStateChange?.(true); - } - if (!e.pointerInside && longPressTimeout.current !== undefined) { clearTimeout(longPressTimeout.current); longPressTimeout.current = undefined; From 288c45825ad39d2ddbb9d17af2ef9726c95d0328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 25 Mar 2026 15:34:10 +0100 Subject: [PATCH 10/13] Unbind actions --- .../apple/Handlers/RNNativeViewHandler.mm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm index 7005d3db2a..842467d43f 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm +++ b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm @@ -167,8 +167,14 @@ - (void)bindToView:(UIView *)view - (void)unbindFromView { + UIView *view = self.recognizer.view; + + if ([view isKindOfClass:[UIControl class]]) { + [(UIControl *)view removeTarget:self action:NULL forControlEvents:UIControlEventAllEvents]; + } + // Restore the React Native's overriden behavor for not delaying content touches - UIScrollView *scrollView = [self retrieveScrollView:self.recognizer.view]; + UIScrollView *scrollView = [self retrieveScrollView:view]; scrollView.delaysContentTouches = NO; [super unbindFromView]; From 1f1d2df6db5ff901661d6e0b481b6c2bff2f4649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 25 Mar 2026 15:58:26 +0100 Subject: [PATCH 11/13] Pressable last event --- .../src/components/Pressable/Pressable.tsx | 7 ++++++- .../src/v3/components/Pressable.tsx | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx b/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx index 350fb5449f..e8ba3fdc1a 100644 --- a/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx +++ b/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx @@ -85,6 +85,7 @@ const LegacyPressable = (props: LegacyPressableProps) => { const isOnPressAllowed = useRef(true); const isCurrentlyPressed = useRef(false); const dimensions = useRef({ width: 0, height: 0 }); + const lastTouchEvent = useRef(null); const normalizedHitSlop: Insets = useMemo( () => @@ -259,6 +260,7 @@ const LegacyPressable = (props: LegacyPressableProps) => { .cancelsTouchesInView(false) .onTouchesDown((event) => { const pressableEvent = gestureTouchToPressableEvent(event); + lastTouchEvent.current = pressableEvent; stateMachine.handleEvent( StateMachineEvent.LONG_PRESS_TOUCHES_DOWN, pressableEvent @@ -303,7 +305,10 @@ const LegacyPressable = (props: LegacyPressableProps) => { } }) .onBegin(() => { - stateMachine.handleEvent(StateMachineEvent.NATIVE_BEGIN); + stateMachine.handleEvent( + StateMachineEvent.NATIVE_BEGIN, + lastTouchEvent.current ?? undefined + ); }) .onStart(() => { if (Platform.OS !== 'android') { diff --git a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx index 6f61fb0fa1..e1e4175c3a 100644 --- a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx @@ -83,6 +83,7 @@ const Pressable = (props: PressableProps) => { width: 0, height: 0, }); + const lastTouchEvent = useRef(null); const normalizedHitSlop: Insets = useMemo( () => @@ -257,6 +258,7 @@ const Pressable = (props: PressableProps) => { cancelsTouchesInView: false, onTouchesDown: (event) => { const pressableEvent = gestureTouchToPressableEvent(event); + lastTouchEvent.current = pressableEvent; stateMachine.handleEvent( StateMachineEvent.LONG_PRESS_TOUCHES_DOWN, pressableEvent @@ -305,7 +307,10 @@ const Pressable = (props: PressableProps) => { } }, onBegin: () => { - stateMachine.handleEvent(StateMachineEvent.NATIVE_BEGIN); + stateMachine.handleEvent( + StateMachineEvent.NATIVE_BEGIN, + lastTouchEvent.current ?? undefined + ); }, onActivate: () => { if (Platform.OS !== 'android' && Platform.OS !== 'ios') { From aa6769fc4a354f560dd71ccefd95e75826ce5e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 26 Mar 2026 12:22:59 +0100 Subject: [PATCH 12/13] Revert "Pressable last event" This reverts commit 1f1d2df6db5ff901661d6e0b481b6c2bff2f4649. --- .../src/components/Pressable/Pressable.tsx | 7 +------ .../src/v3/components/Pressable.tsx | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx b/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx index e8ba3fdc1a..350fb5449f 100644 --- a/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx +++ b/packages/react-native-gesture-handler/src/components/Pressable/Pressable.tsx @@ -85,7 +85,6 @@ const LegacyPressable = (props: LegacyPressableProps) => { const isOnPressAllowed = useRef(true); const isCurrentlyPressed = useRef(false); const dimensions = useRef({ width: 0, height: 0 }); - const lastTouchEvent = useRef(null); const normalizedHitSlop: Insets = useMemo( () => @@ -260,7 +259,6 @@ const LegacyPressable = (props: LegacyPressableProps) => { .cancelsTouchesInView(false) .onTouchesDown((event) => { const pressableEvent = gestureTouchToPressableEvent(event); - lastTouchEvent.current = pressableEvent; stateMachine.handleEvent( StateMachineEvent.LONG_PRESS_TOUCHES_DOWN, pressableEvent @@ -305,10 +303,7 @@ const LegacyPressable = (props: LegacyPressableProps) => { } }) .onBegin(() => { - stateMachine.handleEvent( - StateMachineEvent.NATIVE_BEGIN, - lastTouchEvent.current ?? undefined - ); + stateMachine.handleEvent(StateMachineEvent.NATIVE_BEGIN); }) .onStart(() => { if (Platform.OS !== 'android') { diff --git a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx index e1e4175c3a..6f61fb0fa1 100644 --- a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx @@ -83,7 +83,6 @@ const Pressable = (props: PressableProps) => { width: 0, height: 0, }); - const lastTouchEvent = useRef(null); const normalizedHitSlop: Insets = useMemo( () => @@ -258,7 +257,6 @@ const Pressable = (props: PressableProps) => { cancelsTouchesInView: false, onTouchesDown: (event) => { const pressableEvent = gestureTouchToPressableEvent(event); - lastTouchEvent.current = pressableEvent; stateMachine.handleEvent( StateMachineEvent.LONG_PRESS_TOUCHES_DOWN, pressableEvent @@ -307,10 +305,7 @@ const Pressable = (props: PressableProps) => { } }, onBegin: () => { - stateMachine.handleEvent( - StateMachineEvent.NATIVE_BEGIN, - lastTouchEvent.current ?? undefined - ); + stateMachine.handleEvent(StateMachineEvent.NATIVE_BEGIN); }, onActivate: () => { if (Platform.OS !== 'android' && Platform.OS !== 'ios') { From e6adcb44b55d94cd69afd0f21141dcde216e811a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 26 Mar 2026 12:24:44 +0100 Subject: [PATCH 13/13] Remove misleading comment --- .../react-native-gesture-handler/src/v3/components/Pressable.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx index 6f61fb0fa1..3d05214f5d 100644 --- a/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/Pressable.tsx @@ -310,7 +310,6 @@ const Pressable = (props: PressableProps) => { onActivate: () => { if (Platform.OS !== 'android' && Platform.OS !== 'ios') { // Native.onActivate is broken with Android + hitSlop - // On iOS, onActivate fires on drag (not touch down), so we use onBegin + LONG_PRESS_TOUCHES_DOWN instead stateMachine.handleEvent(StateMachineEvent.NATIVE_START); } },