From 346036c818fcccd37116e3c778016e6bae6e1ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Tue, 4 Nov 2025 15:23:53 +0100 Subject: [PATCH 01/10] Correctly attach NativeViewGestureHandler --- .../apple/Handlers/RNNativeViewHandler.mm | 5 +++++ .../apple/RNGestureHandler.mm | 12 ++++++++---- .../apple/RNGestureHandlerDetector.mm | 13 ++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm index 23c7ed9364..97eda793cb 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm +++ b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm @@ -148,6 +148,11 @@ - (void)bindToView:(UIView *)view [control addTarget:self action:@selector(handleDragExit:forEvent:) forControlEvents:UIControlEventTouchDragExit]; [control addTarget:self action:@selector(handleDragEnter:forEvent:) forControlEvents:UIControlEventTouchDragEnter]; [control addTarget:self action:@selector(handleTouchCancel:forEvent:) forControlEvents:UIControlEventTouchCancel]; + + if (self.actionType == RNGestureHandlerActionTypeNativeDetector) { + [view addGestureRecognizer:_recognizer]; + } + } else { [super bindToView:view]; } diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm index 023cddca1b..21111980b7 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm @@ -389,10 +389,14 @@ - (void)sendEventsInState:(RNGestureHandlerState)state - (RNGHUIView *)findViewForEvents { - return - [self isKindOfClass:[RNNativeViewGestureHandler class]] && _actionType == RNGestureHandlerActionTypeNativeDetector - ? self.recognizer.view.superview - : self.recognizer.view; + if ([self isKindOfClass:[RNNativeViewGestureHandler class]] && + _actionType == RNGestureHandlerActionTypeNativeDetector) { + return [self.recognizer.view.superview isKindOfClass:[RCTViewComponentView class]] + ? self.recognizer.view.superview.superview + : self.recognizer.view.superview; + } + + return self.recognizer.view; } - (void)sendEvent:(RNGestureHandlerStateChange *)event diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm index ce3cd3bb97..b9ae33fb19 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm @@ -5,6 +5,8 @@ #import #import +#import "RNGestureHandlerButtonComponentView.h" + #import #import #import @@ -259,9 +261,18 @@ - (void)tryAttachNativeHandlersToChildView { RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId:_moduleId]; + RNGHUIView *view = self.subviews[0]; + + if ([view isKindOfClass:[RCTViewComponentView class]]) { + RCTViewComponentView *componentView = (RCTViewComponentView *)view; + if (componentView.contentView != nil) { + view = componentView.contentView; + } + } + for (NSNumber *handlerTag in _nativeHandlers) { [handlerManager.registry attachHandlerWithTag:handlerTag - toView:self.subviews[0] + toView:view withActionType:RNGestureHandlerActionTypeNativeDetector]; [_attachedHandlers addObject:handlerTag]; From 65bd778adf75ca4096b10fd9e1213f21b9a1070e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Tue, 4 Nov 2025 15:30:19 +0100 Subject: [PATCH 02/10] Add view as variable --- .../react-native-gesture-handler/apple/RNGestureHandler.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm index 21111980b7..b3459fe868 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm @@ -391,9 +391,9 @@ - (RNGHUIView *)findViewForEvents { if ([self isKindOfClass:[RNNativeViewGestureHandler class]] && _actionType == RNGestureHandlerActionTypeNativeDetector) { - return [self.recognizer.view.superview isKindOfClass:[RCTViewComponentView class]] - ? self.recognizer.view.superview.superview - : self.recognizer.view.superview; + RNGHUIView *view = self.recognizer.view.superview; + + return [view isKindOfClass:[RCTViewComponentView class]] ? view.superview : view; } return self.recognizer.view; From ec0632683f502bad462cc5effb38d0b243a3f4b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Tue, 4 Nov 2025 17:24:46 +0100 Subject: [PATCH 03/10] Check for protocol --- .../apple/RNGestureHandler.mm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm index b3459fe868..8171caf277 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm @@ -13,6 +13,8 @@ #import #import +#import + @interface UIGestureRecognizer (GestureHandler) @property (nonatomic, readonly) RNGestureHandler *gestureHandler; @end @@ -389,14 +391,22 @@ - (void)sendEventsInState:(RNGestureHandlerState)state - (RNGHUIView *)findViewForEvents { + RNGHUIView *view = self.recognizer.view; + if ([self isKindOfClass:[RNNativeViewGestureHandler class]] && _actionType == RNGestureHandlerActionTypeNativeDetector) { - RNGHUIView *view = self.recognizer.view.superview; + if ([view.superview conformsToProtocol:@protocol(RCTRNGestureHandlerDetectorViewProtocol)]) { + return view.superview; + } + + if ([view.superview isKindOfClass:[RCTViewComponentView class]]) { + return view.superview.superview; + } - return [view isKindOfClass:[RCTViewComponentView class]] ? view.superview : view; + return view.superview; } - return self.recognizer.view; + return view; } - (void)sendEvent:(RNGestureHandlerStateChange *)event From a92d664bc5c331037525f62d046c28211e84f617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 12 Nov 2025 15:57:36 +0100 Subject: [PATCH 04/10] Use detector view pointer --- .../apple/Handlers/RNNativeViewHandler.mm | 5 ---- .../apple/RNGestureHandler.h | 2 +- .../apple/RNGestureHandler.mm | 23 ++++--------------- .../apple/RNGestureHandlerDetector.mm | 2 +- .../apple/RNGestureHandlerManager.mm | 10 +------- .../apple/RNGestureHandlerRegistry.m | 1 + 6 files changed, 8 insertions(+), 35 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm index 97eda793cb..23c7ed9364 100644 --- a/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm +++ b/packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm @@ -148,11 +148,6 @@ - (void)bindToView:(UIView *)view [control addTarget:self action:@selector(handleDragExit:forEvent:) forControlEvents:UIControlEventTouchDragExit]; [control addTarget:self action:@selector(handleDragEnter:forEvent:) forControlEvents:UIControlEventTouchDragEnter]; [control addTarget:self action:@selector(handleTouchCancel:forEvent:) forControlEvents:UIControlEventTouchCancel]; - - if (self.actionType == RNGestureHandlerActionTypeNativeDetector) { - [view addGestureRecognizer:_recognizer]; - } - } else { [super bindToView:view]; } diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.h b/packages/react-native-gesture-handler/apple/RNGestureHandler.h index 09126c8060..9e8f4d157f 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.h @@ -81,7 +81,7 @@ @property (nonatomic) BOOL manualActivation; @property (nonatomic) BOOL dispatchesAnimatedEvents; @property (nonatomic) BOOL dispatchesReanimatedEvents; -@property (nonatomic, nullable, assign) NSNumber *hostDetectorTag; +@property (nonatomic, weak, nullable) RNGHUIView *hostDetectorView; @property (nonatomic, nullable, assign) NSNumber *virtualViewTag; - (BOOL)isViewParagraphComponent:(nullable RNGHUIView *)view; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm index 8171caf277..16b20d09fb 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm @@ -13,8 +13,6 @@ #import #import -#import - @interface UIGestureRecognizer (GestureHandler) @property (nonatomic, readonly) RNGestureHandler *gestureHandler; @end @@ -258,7 +256,6 @@ - (void)unbindFromView [self.recognizer.view removeGestureRecognizer:self.recognizer]; self.recognizer.delegate = nil; - self.hostDetectorTag = nil; self.virtualViewTag = nil; [self unbindManualActivation]; @@ -391,22 +388,10 @@ - (void)sendEventsInState:(RNGestureHandlerState)state - (RNGHUIView *)findViewForEvents { - RNGHUIView *view = self.recognizer.view; - - if ([self isKindOfClass:[RNNativeViewGestureHandler class]] && - _actionType == RNGestureHandlerActionTypeNativeDetector) { - if ([view.superview conformsToProtocol:@protocol(RCTRNGestureHandlerDetectorViewProtocol)]) { - return view.superview; - } - - if ([view.superview isKindOfClass:[RCTViewComponentView class]]) { - return view.superview.superview; - } - - return view.superview; - } - - return view; + return _actionType == RNGestureHandlerActionTypeNativeDetector || + _actionType == RNGestureHandlerActionTypeVirtualDetector + ? self.hostDetectorView + : self.recognizer.view; } - (void)sendEvent:(RNGestureHandlerStateChange *)event diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm index 560b59b21e..0b5f7a7d76 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm @@ -194,7 +194,7 @@ - (void)attachHandlers:(const std::vector &)handlerTags } [attachedHandlers addObject:@(tag)]; } - [[handlerManager registry] handlerWithTag:@(tag)].hostDetectorTag = @(self.tag); + [[handlerManager registry] handlerWithTag:@(tag)].hostDetectorView = self; } } diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm index 674db9a6c1..db32785667 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm @@ -295,15 +295,7 @@ - (void)sendEvent:(RNGestureHandlerStateChange *)event // but results in a compilation error. { switch (actionType) { - case RNGestureHandlerActionTypeVirtualDetector: { - NSNumber *hostDetectorTag = [_registry handlerWithTag:event.handlerTag].hostDetectorTag; - detectorView = [self viewForReactTag:hostDetectorTag]; - [self sendNativeOrVirtualEvent:event - withActionType:actionType - forHandlerType:eventHandlerType - forView:detectorView]; - break; - } + case RNGestureHandlerActionTypeVirtualDetector: case RNGestureHandlerActionTypeNativeDetector: { [self sendNativeOrVirtualEvent:event withActionType:actionType diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m index 856c568e53..e78d00ebb0 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m @@ -46,6 +46,7 @@ - (void)attachHandlerWithTag:(NSNumber *)handlerTag - (void)detachHandlerWithTag:(NSNumber *)handlerTag { RNGestureHandler *handler = _handlers[handlerTag]; + handler.hostDetectorView = nil; [handler unbindFromView]; } From e54c63b35b1a0843172f6fc31214b3300f1ed851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 12 Nov 2025 16:28:24 +0100 Subject: [PATCH 05/10] Remove unused import --- .../apple/RNGestureHandlerDetector.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm index 0b5f7a7d76..cae10b19dc 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm @@ -5,8 +5,6 @@ #import #import -#import "RNGestureHandlerButtonComponentView.h" - #import #import #import From 3094904362972b967c0835880af380343a50ac5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 12 Nov 2025 17:20:35 +0100 Subject: [PATCH 06/10] Keep cleanup in unbindFromView --- .../apple/RNGestureHandler.mm | 1 + .../apple/RNGestureHandlerDetector.mm | 18 ++++++++++++++---- .../apple/RNGestureHandlerManager.h | 5 +++++ .../apple/RNGestureHandlerManager.mm | 19 +++++++++++++++++-- .../apple/RNGestureHandlerRegistry.h | 4 ++++ .../apple/RNGestureHandlerRegistry.m | 12 +++++++++++- 6 files changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm index 16b20d09fb..3beadefc36 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm @@ -256,6 +256,7 @@ - (void)unbindFromView [self.recognizer.view removeGestureRecognizer:self.recognizer]; self.recognizer.delegate = nil; + self.hostDetectorView = nil; self.virtualViewTag = nil; [self unbindManualActivation]; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm index cae10b19dc..17c1289cf6 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm @@ -180,15 +180,24 @@ - (void)attachHandlers:(const std::vector &)handlerTags RNGHUIView *targetView = [handlerManager viewForReactTag:@(viewTag)]; if (targetView != nil) { - [handlerManager attachGestureHandler:@(tag) toViewWithTag:@(viewTag) withActionType:actionType]; + [handlerManager attachGestureHandler:@(tag) + toViewWithTag:@(viewTag) + withActionType:actionType + withHostDetector:self]; } else { // Let's assume that if the native view for the virtual detector hasn't been found, the hierarchy was folded // into a single UIView. - [handlerManager.registry attachHandlerWithTag:@(tag) toView:self withActionType:actionType]; + [handlerManager.registry attachHandlerWithTag:@(tag) + toView:self + withActionType:actionType + withHostDetector:self]; [[handlerManager registry] handlerWithTag:@(tag)].virtualViewTag = @(viewTag); } } else { - [handlerManager.registry attachHandlerWithTag:@(tag) toView:self withActionType:actionType]; + [handlerManager.registry attachHandlerWithTag:@(tag) + toView:self + withActionType:actionType + withHostDetector:self]; } [attachedHandlers addObject:@(tag)]; } @@ -273,7 +282,8 @@ - (void)tryAttachNativeHandlersToChildView for (NSNumber *handlerTag in _nativeHandlers) { [handlerManager.registry attachHandlerWithTag:handlerTag toView:view - withActionType:RNGestureHandlerActionTypeNativeDetector]; + withActionType:RNGestureHandlerActionTypeNativeDetector + withHostDetector:self]; [_attachedHandlers addObject:handlerTag]; } diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.h b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.h index 97608df6cd..7e83b286eb 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.h @@ -24,6 +24,11 @@ toViewWithTag:(nonnull NSNumber *)viewTag withActionType:(RNGestureHandlerActionType)actionType; +- (void)attachGestureHandler:(nonnull NSNumber *)handlerTag + toViewWithTag:(nonnull NSNumber *)viewTag + withActionType:(RNGestureHandlerActionType)actionType + withHostDetector:(nullable RNGHUIView *)hostDetector; + - (void)setGestureHandlerConfig:(nonnull NSNumber *)handlerTag config:(nonnull NSDictionary *)config; - (void)updateGestureHandlerConfig:(nonnull NSNumber *)handlerTag config:(nonnull NSDictionary *)config; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm index db32785667..923bbe5861 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm @@ -123,6 +123,14 @@ - (void)createGestureHandler:(NSString *)handlerName tag:(NSNumber *)handlerTag - (void)attachGestureHandler:(nonnull NSNumber *)handlerTag toViewWithTag:(nonnull NSNumber *)viewTag withActionType:(RNGestureHandlerActionType)actionType +{ + [self attachGestureHandler:handlerTag toViewWithTag:viewTag withActionType:actionType withHostDetector:nil]; +} + +- (void)attachGestureHandler:(nonnull NSNumber *)handlerTag + toViewWithTag:(nonnull NSNumber *)viewTag + withActionType:(RNGestureHandlerActionType)actionType + withHostDetector:(nullable RNGHUIView *)hostDetector { RNGHUIView *view = [_viewRegistry viewForReactTag:viewTag]; @@ -151,7 +159,10 @@ - (void)attachGestureHandler:(nonnull NSNumber *)handlerTag dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ if (![_droppedHandlers containsObject:handlerTag]) { - [self attachGestureHandler:handlerTag toViewWithTag:viewTag withActionType:actionType]; + [self attachGestureHandler:handlerTag + toViewWithTag:viewTag + withActionType:actionType + withHostDetector:hostDetector]; } }); } @@ -173,7 +184,11 @@ - (void)attachGestureHandler:(nonnull NSNumber *)handlerTag view.reactTag = viewTag; // necessary for RNReanimated eventHash (e.g. "42onGestureHandlerEvent"), also will be // returned as event.target - [_registry attachHandlerWithTag:handlerTag toView:view withActionType:actionType]; + if (hostDetector != nil) { + [_registry attachHandlerWithTag:handlerTag toView:view withActionType:actionType withHostDetector:hostDetector]; + } else { + [_registry attachHandlerWithTag:handlerTag toView:view withActionType:actionType]; + } // register view if not already there [self registerViewWithGestureRecognizerAttachedIfNeeded:view]; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h index dd73a1ce89..4e47bac008 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h @@ -15,6 +15,10 @@ - (void)attachHandlerWithTag:(nonnull NSNumber *)handlerTag toView:(nonnull RNGHUIView *)view withActionType:(RNGestureHandlerActionType)actionType; +- (void)attachHandlerWithTag:(nonnull NSNumber *)handlerTag + toView:(nonnull RNGHUIView *)view + withActionType:(RNGestureHandlerActionType)actionType + withHostDetector:(nonnull RNGHUIView *)hostDetector; - (void)detachHandlerWithTag:(nonnull NSNumber *)handlerTag; - (void)dropHandlerWithTag:(nonnull NSNumber *)handlerTag; - (void)dropAllHandlers; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m index e78d00ebb0..0504559c87 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m @@ -43,10 +43,20 @@ - (void)attachHandlerWithTag:(NSNumber *)handlerTag [handler bindToView:view]; } +- (void)attachHandlerWithTag:(NSNumber *)handlerTag + toView:(RNGHUIView *)view + withActionType:(RNGestureHandlerActionType)actionType + withHostDetector:(nonnull RNGHUIView *)hostDetector +{ + [self attachHandlerWithTag:handlerTag toView:view withActionType:actionType]; + + RNGestureHandler *handler = _handlers[handlerTag]; + handler.hostDetectorView = hostDetector; +} + - (void)detachHandlerWithTag:(NSNumber *)handlerTag { RNGestureHandler *handler = _handlers[handlerTag]; - handler.hostDetectorView = nil; [handler unbindFromView]; } From 029b77aff2f1e2aad18830f31294399aeab1ed81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 12 Nov 2025 17:27:30 +0100 Subject: [PATCH 07/10] Add helper --- .../apple/RNGestureHandler.h | 1 + .../apple/RNGestureHandler.mm | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.h b/packages/react-native-gesture-handler/apple/RNGestureHandler.h index 9e8f4d157f..598375b696 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.h @@ -108,6 +108,7 @@ - (nullable RNGHUIScrollView *)retrieveScrollView:(nonnull RNGHUIView *)view; - (nonnull RNGHUIView *)findViewForEvents; - (BOOL)wantsToAttachDirectlyToView; +- (BOOL)usesNativeOrVirtualDetector; #if !TARGET_OS_OSX - (BOOL)isUIScrollViewPanGestureRecognizer:(nonnull UIGestureRecognizer *)gestureRecognizer; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm index 3beadefc36..e4dfee2e3e 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandler.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandler.mm @@ -229,6 +229,12 @@ - (UITouchType)getPointerType return (UITouchType)_pointerType; } +- (BOOL)usesNativeOrVirtualDetector +{ + return _actionType == RNGestureHandlerActionTypeNativeDetector || + _actionType == RNGestureHandlerActionTypeVirtualDetector; +} + - (BOOL)isViewParagraphComponent:(RNGHUIView *)view { return [view isKindOfClass:[RCTParagraphComponentView class]]; @@ -389,10 +395,7 @@ - (void)sendEventsInState:(RNGestureHandlerState)state - (RNGHUIView *)findViewForEvents { - return _actionType == RNGestureHandlerActionTypeNativeDetector || - _actionType == RNGestureHandlerActionTypeVirtualDetector - ? self.hostDetectorView - : self.recognizer.view; + return [self usesNativeOrVirtualDetector] ? self.hostDetectorView : self.recognizer.view; } - (void)sendEvent:(RNGestureHandlerStateChange *)event From 9138f234bce9bddd859cf5d481037dc1bbd19f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 13 Nov 2025 15:26:10 +0100 Subject: [PATCH 08/10] Remove unnecessary assignment --- .../apple/RNGestureHandlerDetector.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm index 17c1289cf6..b5e0059608 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm @@ -201,7 +201,6 @@ - (void)attachHandlers:(const std::vector &)handlerTags } [attachedHandlers addObject:@(tag)]; } - [[handlerManager registry] handlerWithTag:@(tag)].hostDetectorView = self; } } From e5d16664d737a31f137f728b77ce84c01820e9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 13 Nov 2025 15:32:56 +0100 Subject: [PATCH 09/10] swap implementations --- .../apple/RNGestureHandlerRegistry.h | 2 +- .../apple/RNGestureHandlerRegistry.m | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h index 4e47bac008..ea5efba286 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h @@ -18,7 +18,7 @@ - (void)attachHandlerWithTag:(nonnull NSNumber *)handlerTag toView:(nonnull RNGHUIView *)view withActionType:(RNGestureHandlerActionType)actionType - withHostDetector:(nonnull RNGHUIView *)hostDetector; + withHostDetector:(nullable RNGHUIView *)hostDetector; - (void)detachHandlerWithTag:(nonnull NSNumber *)handlerTag; - (void)dropHandlerWithTag:(nonnull NSNumber *)handlerTag; - (void)dropAllHandlers; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m index 0504559c87..0137a2578d 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m @@ -36,22 +36,23 @@ - (void)attachHandlerWithTag:(NSNumber *)handlerTag toView:(RNGHUIView *)view withActionType:(RNGestureHandlerActionType)actionType { - RNGestureHandler *handler = _handlers[handlerTag]; - RCTAssert(handler != nil, @"Handler for tag %@ does not exists", handlerTag); - [handler unbindFromView]; - handler.actionType = actionType; - [handler bindToView:view]; + [self attachHandlerWithTag:handlerTag toView:view withActionType:actionType withHostDetector:nil]; } - (void)attachHandlerWithTag:(NSNumber *)handlerTag toView:(RNGHUIView *)view withActionType:(RNGestureHandlerActionType)actionType - withHostDetector:(nonnull RNGHUIView *)hostDetector + withHostDetector:(nullable RNGHUIView *)hostDetector { - [self attachHandlerWithTag:handlerTag toView:view withActionType:actionType]; - RNGestureHandler *handler = _handlers[handlerTag]; - handler.hostDetectorView = hostDetector; + RCTAssert(handler != nil, @"Handler for tag %@ does not exists", handlerTag); + [handler unbindFromView]; + handler.actionType = actionType; + [handler bindToView:view]; + + if (hostDetector != nil) { + handler.hostDetectorView = hostDetector; + } } - (void)detachHandlerWithTag:(NSNumber *)handlerTag From a0ed05553d68770556ff45236ce4ffd8c8184ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 13 Nov 2025 15:43:50 +0100 Subject: [PATCH 10/10] Remove unused implementation --- .../apple/RNGestureHandlerManager.mm | 6 +----- .../apple/RNGestureHandlerRegistry.h | 3 --- .../apple/RNGestureHandlerRegistry.m | 7 ------- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm index 923bbe5861..b221e4dcde 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm @@ -184,11 +184,7 @@ - (void)attachGestureHandler:(nonnull NSNumber *)handlerTag view.reactTag = viewTag; // necessary for RNReanimated eventHash (e.g. "42onGestureHandlerEvent"), also will be // returned as event.target - if (hostDetector != nil) { - [_registry attachHandlerWithTag:handlerTag toView:view withActionType:actionType withHostDetector:hostDetector]; - } else { - [_registry attachHandlerWithTag:handlerTag toView:view withActionType:actionType]; - } + [_registry attachHandlerWithTag:handlerTag toView:view withActionType:actionType withHostDetector:hostDetector]; // register view if not already there [self registerViewWithGestureRecognizerAttachedIfNeeded:view]; diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h index ea5efba286..a3c31d7766 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h @@ -12,9 +12,6 @@ - (nullable RNGestureHandler *)handlerWithTag:(nonnull NSNumber *)handlerTag; - (void)registerGestureHandler:(nonnull RNGestureHandler *)gestureHandler; -- (void)attachHandlerWithTag:(nonnull NSNumber *)handlerTag - toView:(nonnull RNGHUIView *)view - withActionType:(RNGestureHandlerActionType)actionType; - (void)attachHandlerWithTag:(nonnull NSNumber *)handlerTag toView:(nonnull RNGHUIView *)view withActionType:(RNGestureHandlerActionType)actionType diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m index 0137a2578d..15e2b0985e 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m @@ -32,13 +32,6 @@ - (void)registerGestureHandler:(RNGestureHandler *)gestureHandler _handlers[gestureHandler.tag] = gestureHandler; } -- (void)attachHandlerWithTag:(NSNumber *)handlerTag - toView:(RNGHUIView *)view - withActionType:(RNGestureHandlerActionType)actionType -{ - [self attachHandlerWithTag:handlerTag toView:view withActionType:actionType withHostDetector:nil]; -} - - (void)attachHandlerWithTag:(NSNumber *)handlerTag toView:(RNGHUIView *)view withActionType:(RNGestureHandlerActionType)actionType