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 ffd10bc6f236..d9e3b901824e 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -692,9 +692,11 @@ - (void)prepareForRecycle _state.reset(); const auto &props = static_cast(*_props); - _scrollView.contentOffset = RCTCGPointFromPoint(props.contentOffset); - // Reset zoom scale to default + // Reset zoom scale to default. This must happen before resetting contentOffset: + // in RTL the mirroring transform makes UIKit report zoomScale == -1, and changing + // it to 1 makes UIKit move contentOffset. _scrollView.zoomScale = 1.0; + _scrollView.contentOffset = RCTCGPointFromPoint(props.contentOffset); // Invalidate cached content size so that updateState: recalculates the // container frame after zoomScale reset (which may have mutated it in RTL). _contentSize = CGSizeZero;