Conversation
Contributor
Author
|
CI fails for reasons unrelated to this PR and should be fixed by #3465. |
kmichalikk
approved these changes
Dec 10, 2025
t0maboro
approved these changes
Dec 10, 2025
kkafar
approved these changes
Dec 10, 2025
This was referenced Mar 24, 2026
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.
Description
Fixes bottom accessory content view switching workaround on appearance change.
before.mov
after.mov
Thanks to @Ubax for reporting the bug.
Reasoning
For RN >= 0.82, bottom accessory uses "content view switching"/"double-rendering" workaround (more details in PR description of #3288). Two bottom accessories are rendered by JS - one for regular environment, one for inline environment and both are inserted to bottom accessory view on the native side. To control which version is visible, we change
view.layer.opacitydepending on current environment. Opacity is also controlled byRCTViewComponentViewininvalidateLayermethod. It is called in 2 places:finalizeUpdates,traitCollectionDidChange:.invalidateLayeroverrides our custom opacity, that's why we update it by callinghandleContentViewVisibilityForEnvironmentIfNeededinRNSBottomAccessoryContentComponentView'sfinalizeUpdatesaftersuperimplementation is called.The same was missing for
traitCollectionDidChange. The layer invalidation is called when[self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection](=> when appearance changes).traitCollectionDidChangeis a deprecated API for handling trait changes. For detecting current bottom accessory environment, we useregisterForTraitChanges:withHandler:. Unfortunately, we can't use new API for updating opacity astraitCollectionDidChangeis called after handlers registered viaregisterForTraitChanges:withHandler:.In the future, if
RCTViewComponentViewswitches to new API, we will need to adapt as well. Here is some research that might become useful:hasDifferentColorAppearanceComparedToTraitCollection:can be replaced with new API andsystemTraitsAffectingColorAppearancebut this API is available on iOS 17+, so we'll need to fallback to hardcoded traits array. Information about which traits affect color appearance can be found in in-code docs forhasDifferentColorAppearanceComparedToTraitCollection:We can also research whether it would be possible to update opacity style/prop directly in ShadowNode instead of only native side. There is an existing ticket to research this: https://github.com/software-mansion/react-native-screens-labs/issues/558.
Changes
RCTViewComponentViewinvalidates layer on appearance changeTest code and steps to reproduce
Run
Test3288. You can modify bottom accessory by changing prop passed toBottomTabsContainerto:Checklist