From 8c39a6717dc598d9a618e66151b5e10a449013f2 Mon Sep 17 00:00:00 2001 From: Sorin Cioban Date: Tue, 2 Jun 2026 20:34:51 +0100 Subject: [PATCH] Respect JS responder inside Fabric ScrollView --- .../ScrollView/RCTScrollViewComponentView.mm | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 548987ff291d..f73f9e618bc4 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -572,8 +572,24 @@ - (void)unmountChildComponentView:(UIView *)childCompo * Returns whether or not the scroll view interaction should be blocked because * JavaScript was found to be the responder. */ -- (BOOL)_shouldDisableScrollInteraction +- (BOOL)_shouldDisableScrollInteractionForContentView:(UIView *)contentView { + UIView *view = contentView; + while (view) { + if ([view respondsToSelector:@selector(isJSResponder)]) { + BOOL isJSResponder = ((UIView *)view).isJSResponder; + if (isJSResponder) { + return YES; + } + } + + if (view == self) { + break; + } + + view = view.superview; + } + UIView *ancestorView = self.superview; while (ancestorView) { @@ -736,11 +752,11 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView static_cast(*_eventEmitter).onScrollEndDrag(metrics); } -- (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view +- (BOOL)touchesShouldCancelInContentView:(UIView *)view { // Historically, `UIScrollView`s in React Native do not cancel touches // started on `UIControl`-based views (as normal iOS `UIScrollView`s do). - return ![self _shouldDisableScrollInteraction]; + return ![self _shouldDisableScrollInteractionForContentView:view]; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView