diff --git a/packages/react-native-gesture-handler/apple/RNGestureHandler.h b/packages/react-native-gesture-handler/apple/RNGestureHandler.h index 09126c8060..598375b696 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; @@ -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 023cddca1b..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]]; @@ -256,7 +262,7 @@ - (void)unbindFromView [self.recognizer.view removeGestureRecognizer:self.recognizer]; self.recognizer.delegate = nil; - self.hostDetectorTag = nil; + self.hostDetectorView = nil; self.virtualViewTag = nil; [self unbindManualActivation]; @@ -389,10 +395,7 @@ - (void)sendEventsInState:(RNGestureHandlerState)state - (RNGHUIView *)findViewForEvents { - return - [self isKindOfClass:[RNNativeViewGestureHandler class]] && _actionType == RNGestureHandlerActionTypeNativeDetector - ? self.recognizer.view.superview - : self.recognizer.view; + return [self usesNativeOrVirtualDetector] ? 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 ecc4a79322..b5e0059608 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm @@ -180,19 +180,27 @@ - (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)]; } - [[handlerManager registry] handlerWithTag:@(tag)].hostDetectorTag = @(self.tag); } } @@ -261,10 +269,20 @@ - (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] - withActionType:RNGestureHandlerActionTypeNativeDetector]; + toView:view + 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 674db9a6c1..b221e4dcde 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,7 @@ - (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]; + [_registry attachHandlerWithTag:handlerTag toView:view withActionType:actionType withHostDetector:hostDetector]; // register view if not already there [self registerViewWithGestureRecognizerAttachedIfNeeded:view]; @@ -295,15 +306,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.h b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h index dd73a1ce89..a3c31d7766 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.h @@ -14,7 +14,8 @@ - (void)registerGestureHandler:(nonnull RNGestureHandler *)gestureHandler; - (void)attachHandlerWithTag:(nonnull NSNumber *)handlerTag toView:(nonnull RNGHUIView *)view - withActionType:(RNGestureHandlerActionType)actionType; + withActionType:(RNGestureHandlerActionType)actionType + 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 856c568e53..15e2b0985e 100644 --- a/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m +++ b/packages/react-native-gesture-handler/apple/RNGestureHandlerRegistry.m @@ -35,12 +35,17 @@ - (void)registerGestureHandler:(RNGestureHandler *)gestureHandler - (void)attachHandlerWithTag:(NSNumber *)handlerTag toView:(RNGHUIView *)view withActionType:(RNGestureHandlerActionType)actionType + withHostDetector:(nullable RNGHUIView *)hostDetector { RNGestureHandler *handler = _handlers[handlerTag]; 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