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 d8ee6cb3d8b..fde373ba822 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -437,7 +437,7 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - if (!_isUserTriggeredScrolling) { + if (!_isUserTriggeredScrolling || CoreFeatures::enableGranularScrollViewStateUpdatesIOS) { [self _updateStateWithContentOffset]; } diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index 7b09c995700..8608d8b042f 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -276,6 +276,10 @@ static BackgroundExecutor RCTGetBackgroundExecutor() CoreFeatures::disableTransactionCommit = true; } + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_granular_scroll_view_state_updates_ios")) { + CoreFeatures::enableGranularScrollViewStateUpdatesIOS = true; + } + auto componentRegistryFactory = [factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)]( EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) { diff --git a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp index 351a257d678..cbfd5cf3b10 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp @@ -16,5 +16,6 @@ bool CoreFeatures::useNativeState = false; bool CoreFeatures::cacheLastTextMeasurement = false; bool CoreFeatures::cancelImageDownloadsOnRecycle = false; bool CoreFeatures::disableTransactionCommit = false; +bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h index f9a07875d27..a204428d15d 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h @@ -48,6 +48,10 @@ class CoreFeatures { // [CATransaction end] This feature flag disables it to measure its impact in // production. static bool disableTransactionCommit; + + // When enabled, RCTScrollViewComponentView will trigger ShadowTree state + // updates for all changes in scroll position. + static bool enableGranularScrollViewStateUpdatesIOS; }; } // namespace facebook::react