Repository navigation
[iOS] Reset ScrollView frame when recycling - #59362
Open
kirillzyusko wants to merge 1 commit into
Open
kirillzyusko wants to merge 1 commit into
kirillzyusko wants to merge 1 commit into
Conversation
kirillzyusko
marked this pull request as ready for review
October 22, 2026 17:06
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
An interactive native-stack swipe-back with keyboard dismissal and native-driven
Animatedheight updates can leave the internalUIScrollViewwith a negative frame origin.prepareForRecycleresets the outer component's frame, but retains the inner view's geometry. Reopening the screen reuses that offset view, shifting its content upward and leaving a gap at the bottom.Reset
_scrollView.frametoself.boundsat the end ofprepareForRecycle.Warning
To reproduce this problem I had to use new experimental shared Animated backend + drive
heightupdates. And also use native-stack. I didn't find a way to reproduce it withoutreact-native-screens/native-stack, but I strongly believe that root cause lives inreact-nativecore.Minimal runnable reproduction | App.js code | Reproduction changes
The repro uses React Native Animated, native-stack, screens and safe-area-context. It has no Reanimated, Worklets or keyboard-controller dependency (though original problem was discovered with
react-native-keyboard-controller(#1200) /react-native-reanimated/react-native-worklets- in this PR I tried to isolate changes as close to bare RN as possible, but I still had to usereact-native-screensfor native navigation with gestures and all that stuff. Without navigation I didn't find a way to reproduce this problem - but repro confirms that it's not reanimated/keyboard-controlelr specific issue).The public Experimental release preset enables the shared Animated backend and C++ Native Animated.
Related report: react-native-keyboard-controller#1200.
Changelog:
[IOS] [FIXED] - Reset the inner ScrollView frame when recycling to prevent a stale offset on reuse.
Test Plan:
Verified using iPhone 16 Pro Simulator (iOS 18.5), Xcode 27.0, React Native 0.87.1 / Fabric.
Reproduction
At the pinned reproduction commit:
Enable the simulator's software keyboard. The interpolation constants target this device's 402 × 874 pt screen.
Important
The first opening maps native
onScrollevents to height usingAnimated.eventwithuseNativeDriver: true. Keyboard dismissal triggers a second resize after 100 ms.Then run
yarn apply-fix, rebuild withyarn ios --simulator "iPhone 16 Pro", and repeat the same steps.Results
Screenshots — iPhone 16 Pro Simulator, iOS 18.5
Videos — iPhone 16 Pro Simulator, iOS 18.5
before.mp4
after-english.mp4