-
-
Notifications
You must be signed in to change notification settings - Fork 630
Bottom accessory content view opacity glitch: invalidateLayer resets visibility #3798
Description
Description
The bottom accessory content view visibility switching (for RN >= 0.82, dual-content-view approach) can glitch, showing the wrong content view (e.g., the inline copy when the tab bar is in regular/expanded state). This makes UI elements that are conditionally rendered per-placement inaccessible.
RCTViewComponentView.invalidateLayer unconditionally resets self.layer.opacity to the React props value (typically 1.0). This overwrites the 0.0 opacity that RNSTabsBottomAccessoryHelper sets to hide the inactive content view.
The existing mitigations call handleContentViewVisibilityForEnvironmentIfNeeded after:
finalizeUpdates:(original fix)traitCollectionDidChange:(fix in fix(iOS, Tabs): bottom accessory opacity on appearance change #3467)
However, invalidateLayer can be triggered from other code paths not covered by these two (mount/unmount cycles of the accessory, prop changes on parent views, animated transitions). When this happens, opacity is reset to 1.0 on both content views, leaving both copies visible simultaneously.
Proposed fix: Override invalidateLayer directly on RNSTabsBottomAccessoryContentComponentView:
- (void)invalidateLayer
{
[super invalidateLayer];
[_accessoryView.helper handleContentViewVisibilityForEnvironmentIfNeeded];
}Steps to reproduce
- Use
NativeTabs.BottomAccessorywith different content forregularvsinlineplacement (e.g., extra buttons only in regular mode) - Set
minimizeBehavior="onScrollDown"on NativeTabs - Scroll down on a tab with native scroll to collapse the tab bar (accessory goes inline)
- Switch to a tab where the scroll view does not reach the native tab bar (tab bar expands back)
- The inline content view persists while the tab bar is in expanded/regular state
The glitch is intermittent and more likely when the accessory mount coincides with other prop changes on NativeTabs.
Snack or a link to a repository
We do not have a minimal reproduction repo yet. The issue occurs in a production app with NativeTabs bottom accessory. The root cause is clear from reading the native source: RCTViewComponentView.invalidateLayer resets layer.opacity and only two of many possible call sites are mitigated.
Screens version
4.24.0
React Native version
0.83.2
Platforms
- iOS
JavaScript runtime
Hermes
Workflow
Expo managed workflow
Architecture
Fabric (New Architecture)
Build type
Debug mode
Device
Real device
Device model
iPhone 16 Pro (iOS 26.0 beta)
Acknowledgements
Yes