You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It does not seem like contentInset or contentOffset is reset when prepareForRecyle is run on ScrollViews on iOS for New Architecture.
This is most noticeable when using centerContent={true} on ScrollViews with some height and not much content. If you unmount such a ScrollView, and mount another with small height (like a horizontal ScrollView in my example here), you will notice the content in the horizontal one is displaced quite a bit.
This is because the native RCTEnhancedScrollView is recycled between those mounts, and the inset and offset is re-used (see logs and video). This is not a problem on the old architecture.
If I apply a patch to actually recalculate the content inset on props change it fixes the issue: cbrevik@23d270c
Admittedly it does introduce some more coupling between RCTEnhancedScrollView and RCTScrollViewComponentView which might not be the best solution. And there are maybe more scenarios than what I've tested this will affect.
Click Playground tab, and see that low-height horizontal ScrollView is at the top (as it should be).
Click Vertical ScrollView With Centered Content-button, and notice that the content of vertical scroll view is at top (and not centered), which is a bug.
Click Low Height Horizontal Scroll-button, and notice that now the low-height horizontal ScrollView is further down on the screen. Also a bug.
React Native Version
0.83.1
Affected Platforms
Runtime - iOS
Areas
Fabric - The New Renderer
Output of npx @react-native-community/cli info
System:
OS: macOS 15.6.1
CPU: (10) arm64 Apple M1 Pro
Memory: 1.17 GB / 32.00 GB
Shell:
version: 4.0.2
path: /opt/homebrew/bin/fish
Binaries:
Node:
version: 22.17.1
path: /usr/local/bin/node
Yarn:
version: 1.22.22
path: /opt/homebrew/bin/yarn
npm:
version: 10.9.2
path: /usr/local/bin/npm
Watchman:
version: 2025.08.11.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.15.2
path: /Users/cb/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.1
- iOS 26.1
- macOS 26.1
- tvOS 26.1
- visionOS 26.1
- watchOS 26.1
Android SDK:
API Levels:
- "31"
- "34"
- "35"
- "36"
Build Tools:
- 34.0.0
- 35.0.0
- 36.0.0
System Images:
- android-35 | Google APIs ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
- android-35 | Pre-Release 16 KB Page Size Google Play ARM 64 v8a
- android-36 | Google APIs ARM 64 v8a
- android-36 | Google Play ARM 64 v8a
- android-36 | Pre-Release 16 KB Page Size Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2025.1 AI-251.26094.121.2512.13930704
Xcode:
version: 26.1.1/17B100
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.16
path: /usr/bin/javac
Ruby:
version: 3.2.0
path: /Users/cb/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli": Not Found
react: Not Found
react-native: Not Found
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: false
newArchEnabled: false
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
If I capture view hierarchy in Xcode, at first the horizontal ScrollView has this state:
Here the offset and inset is actually wrong, since it is supposed to center the content in the screen: contentOffset: {0, 0}; contentSize: {382, 300}; adjustedContentInset: {0, 0, 0, 0}
It has "inherited" those from the horizontal ScrollView. If I navigate back to the horizontal ScrollView:
Now these are wrong: contentOffset: {0, -180.66666666666666}; contentSize: {200, 20}; adjustedContentInset: {180.66666666666663, 0, 180.66666666666663, 0}
It has actually inherited the "center content" offset/inset from the vertical ScrollView.
On next navigate back to vertical, the content is properly centered for that ScrollView, but wrong going forward for the horizontal one.
Notice the pointer 0x10cdc0e00 is the same for all instances, so it actually recycled the same native ScrollView.
Description
It does not seem like
contentInsetorcontentOffsetis reset whenprepareForRecyleis run on ScrollViews on iOS for New Architecture.This is most noticeable when using
centerContent={true}on ScrollViews with some height and not much content. If you unmount such aScrollView, and mount another with small height (like a horizontalScrollViewin my example here), you will notice the content in the horizontal one is displaced quite a bit.This is because the native
RCTEnhancedScrollViewis recycled between those mounts, and the inset and offset is re-used (see logs and video). This is not a problem on the old architecture.If I apply a patch to actually recalculate the content inset on props change it fixes the issue: cbrevik@23d270c
Admittedly it does introduce some more coupling between
RCTEnhancedScrollViewandRCTScrollViewComponentViewwhich might not be the best solution. And there are maybe more scenarios than what I've tested this will affect.Steps to reproduce
Playgroundtab, and see that low-height horizontal ScrollView is at the top (as it should be).Vertical ScrollView With Centered Content-button, and notice that the content of vertical scroll view is at top (and not centered), which is a bug.Low Height Horizontal Scroll-button, and notice that now the low-height horizontal ScrollView is further down on the screen. Also a bug.React Native Version
0.83.1
Affected Platforms
Runtime - iOS
Areas
Fabric - The New Renderer
Output of
npx @react-native-community/cli infoStacktrace or Logs
If I capture view hierarchy in Xcode, at first the horizontal ScrollView has this state:
Note the inset and offset:
contentOffset: {0, 0}; contentSize: {200, 20}; adjustedContentInset: {0, 0, 0, 0}If I navigate to the taller vertical ScrollView (and capture), it has this state:
Here the offset and inset is actually wrong, since it is supposed to center the content in the screen:
contentOffset: {0, 0}; contentSize: {382, 300}; adjustedContentInset: {0, 0, 0, 0}It has "inherited" those from the horizontal ScrollView. If I navigate back to the horizontal ScrollView:
Now these are wrong:
contentOffset: {0, -180.66666666666666}; contentSize: {200, 20}; adjustedContentInset: {180.66666666666663, 0, 180.66666666666663, 0}It has actually inherited the "center content" offset/inset from the vertical ScrollView.
On next navigate back to vertical, the content is properly centered for that ScrollView, but wrong going forward for the horizontal one.
Notice the pointer
0x10cdc0e00is the same for all instances, so it actually recycled the same native ScrollView.MANDATORY Reproducer
https://github.com/cbrevik/react-native/blob/0cd46dcec7521f4697c47b1a264b065cd4ca8c59/packages/rn-tester/js/examples/Playground/RNTesterPlayground.js
Screenshots and Videos
Bugged Recycled ScrollView
bugged_recycled_scrollview.mov
Fixed Recycled ScrollView (with my patch)
fixed-recycled-scrollview.mov