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 fc33f648bb6..671f3387d03 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -119,6 +119,10 @@ RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrollView, NSInt // Once an accessibility API is used, view culling will be disabled for the entire session. BOOL _isAccessibilityAPIUsed; + // Flag to temporarily disable maintainVisibleContentPosition adjustments during immediate state updates + // to prevent conflicts between immediate content offset updates and visible content position logic + BOOL _avoidAdjustmentForMaintainVisibleContentPosition; + RCTVirtualViewContainerState *_virtualViewContainerState; } @@ -640,6 +644,11 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu return; } + BOOL enableImmediateUpdateModeForContentOffsetChanges = + ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(); + + _avoidAdjustmentForMaintainVisibleContentPosition = enableImmediateUpdateModeForContentOffsetChanges; + auto contentOffset = RCTPointFromCGPoint(_scrollView.contentOffset); BOOL isAccessibilityAPIUsed = _isAccessibilityAPIUsed; _state->updateState( @@ -655,9 +664,10 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu UIAccessibilityIsVoiceOverRunning() || UIAccessibilityIsSwitchControlRunning() || isAccessibilityAPIUsed; return std::make_shared(newData); }, - ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges() - ? EventQueue::UpdateMode::unstable_Immediate - : EventQueue::UpdateMode::Asynchronous); + enableImmediateUpdateModeForContentOffsetChanges ? EventQueue::UpdateMode::unstable_Immediate + : EventQueue::UpdateMode::Asynchronous); + + _avoidAdjustmentForMaintainVisibleContentPosition = NO; } - (void)prepareForRecycle @@ -1057,7 +1067,7 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu - (void)_adjustForMaintainVisibleContentPosition { const auto &props = static_cast(*_props); - if (!props.maintainVisibleContentPosition) { + if (!props.maintainVisibleContentPosition || _avoidAdjustmentForMaintainVisibleContentPosition) { return; }