-
-
Notifications
You must be signed in to change notification settings - Fork 532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong headerTitle layout when pushing screen with keyboard on new arch #2232
Labels
NewArch
Issues related only to new architecture
Platform: iOS
This issue is specific to iOS
Repro provided
A reproduction with a snack or repo is provided
Comments
github-actions
bot
added
Repro provided
A reproduction with a snack or repo is provided
Platform: iOS
This issue is specific to iOS
labels
Jul 5, 2024
Hi @janicduplessis, thanks for creating this issue! |
@janicduplessis I can confirm it is reproducible even without opening the keyboard. @tboba Unfortunately the PR you mentioned does not fix this issue. I'll take a look at it |
1 task
4 tasks
kkafar
added a commit
that referenced
this issue
Jul 29, 2024
…2263) ## Description This PR fixes #2232 by disabling view recycling in `RNSScreenStackHeaderSubview` view component, as no better solution was found. The following sequence leads to the bug: 1. User clicks back button 2. The header subviews are properly removed and put in recycle pool in the same order they were mounted (recycle pool is a stack). 3. User pushes again just-popped-screen. 4. React Native reuses view from recycle pool, but `headerCenter` is to be mounted first, so RN reuses the view that was previously `headerRight` (because it is on top of the recycle pool stack). Similarly the second view in recycle pool, which was previously `headerCenter` is now repurposed as `headerRight`. 5. RN sets correct frames for both subviews. 6. System sets wrong frame for the new `headerCenter` due to layout triggered by `setNavigationBarHidden` in `updateViewController` of `RNSScreenStackHeaderConfig`. The `setNavigationBarHidden` is called, because there is difference in value of the prop between the screens (see issue for repro). The only fact that matters is the one, that native layout is triggered & it computes the `width` incorrectly <- it looks like UIKit does hold some cache for layout computations & when seeing the recycled view it just bonks it with it's previous frame, for some reason not observing that deeper in view hierarchy contents have changed. I've tried to invalidate layout of the subview in various places that could make sense, e.g. `prepareForRecycle`, just before computing native layout in `updateViewController`, etc. for no result. To avoid putting more debugging hours into this particular issue I went with disabling view recycling for header subviews, originally suggested by @janicduplessis in the issue description. ### Open questions We would want to answer those at some time in the future: 1. [ ] What's the difference between JS-initiated dismissal and native one, in this very case? Where does the difference in behaviour come from? (JS-initiated works properly) 2. [ ] In what other way can we solve this w/o disabling view recycling? Fixes #2232 ## Changes Disable view recycling in `RNSScreenStackHeaderSubview` view component. ## Test code and steps to reproduce `Test2232` ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes
ja1ns
pushed a commit
to WiseOwlTech/react-native-screens
that referenced
this issue
Oct 9, 2024
…oftware-mansion#2263) ## Description This PR fixes software-mansion#2232 by disabling view recycling in `RNSScreenStackHeaderSubview` view component, as no better solution was found. The following sequence leads to the bug: 1. User clicks back button 2. The header subviews are properly removed and put in recycle pool in the same order they were mounted (recycle pool is a stack). 3. User pushes again just-popped-screen. 4. React Native reuses view from recycle pool, but `headerCenter` is to be mounted first, so RN reuses the view that was previously `headerRight` (because it is on top of the recycle pool stack). Similarly the second view in recycle pool, which was previously `headerCenter` is now repurposed as `headerRight`. 5. RN sets correct frames for both subviews. 6. System sets wrong frame for the new `headerCenter` due to layout triggered by `setNavigationBarHidden` in `updateViewController` of `RNSScreenStackHeaderConfig`. The `setNavigationBarHidden` is called, because there is difference in value of the prop between the screens (see issue for repro). The only fact that matters is the one, that native layout is triggered & it computes the `width` incorrectly <- it looks like UIKit does hold some cache for layout computations & when seeing the recycled view it just bonks it with it's previous frame, for some reason not observing that deeper in view hierarchy contents have changed. I've tried to invalidate layout of the subview in various places that could make sense, e.g. `prepareForRecycle`, just before computing native layout in `updateViewController`, etc. for no result. To avoid putting more debugging hours into this particular issue I went with disabling view recycling for header subviews, originally suggested by @janicduplessis in the issue description. ### Open questions We would want to answer those at some time in the future: 1. [ ] What's the difference between JS-initiated dismissal and native one, in this very case? Where does the difference in behaviour come from? (JS-initiated works properly) 2. [ ] In what other way can we solve this w/o disabling view recycling? Fixes software-mansion#2232 ## Changes Disable view recycling in `RNSScreenStackHeaderSubview` view component. ## Test code and steps to reproduce `Test2232` ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
NewArch
Issues related only to new architecture
Platform: iOS
This issue is specific to iOS
Repro provided
A reproduction with a snack or repo is provided
Description
When pushing a new screen that has
headerTitle
,headerRight
and an autoFocus TextInput the layout of theheaderTitle
is incorrect the 2nd time the screen is opened.Workaround:
Disable view recycling in RNSScreenStackHeaderSubview
Not sure if it would be an acceptable fix, but disabling view recycling does fix the problem.
Steps to reproduce
Using this code in FabricExample app HeaderOptions.tsx
Note: If using iOS simulator make sure to toggle the software keyboard.
First open:
2nd open:
Weirdly this doesn't repro if no headerRight is set or if the keyboard is not opened.
Snack or a link to a repository
https://github.com/janicduplessis/react-native-screens/tree/%40janic/header-bug-2
Screens version
main@e5a6220
React Native version
0.74
Platforms
iOS
JavaScript runtime
Hermes
Workflow
React Native (without Expo)
Architecture
Fabric (New Architecture)
Build type
Debug mode
Device
iOS simulator
Device model
No response
Acknowledgements
Yes
The text was updated successfully, but these errors were encountered: