Skip to content

Conversation

@kligarski
Copy link
Contributor

@kligarski kligarski commented Dec 17, 2025

Description

Adds customization of backgroundColor for native tabs container (UITabBarController.view on iOS, TabsHost on Android) and tab screen (RNSBottomTabsScreenComponentView on iOS, TabScreen on Android).

Android iOS
3492_Android.mp4
3492_iOS.mov

Closes https://github.com/software-mansion/react-native-screens-labs/issues/721.
Supersedes #3478.

Comparison of different approaches to setting background color on iOS

This PR allows for (at least) 3 kinds of setting background color in tabs. Due to asynchronous nature, different approaches result in different effect.

Tab screen + React View has background color

This is similar to current approach where tab screen uses systemBackgroundColor and user defines background color via View inside components passed to tab screen. This approach was used to mitigate problems with liquid glass tab bar appearance adaptation (more details: #3279).

bg_tab_and_react.mov

First, background color of tab screen is visible before tab's content is rendered by React and correct color appears.

Only React View has background color

This is similar to approach suggested in #3478 (transparent screen). While this seems to work better on first tab renders, switching between similar tabs after they are rendered causes a flash.

bg_only_react.mov

This is reproducible in bare UIKit app when child VC's view has clear background color and its subview has different background color.

Only Tab screen has background color

This approach is possible thanks to this PR and it is closes to native platform but tab's content still appears after a delay because it needs to be rendered by React - this causes a flash on first render.

bg_only_tab.mov

Changes

  • add nativeContainerStyle prop to BottomTabs component with backgroundColor field
  • add style prop to BottomTabsScreen component with backgroundColor field
  • add Test3492

Test code and steps to reproduce

Run Test3492.

Checklist

  • Included code example that can be used to test this change
  • Ensured that CI passes

Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've watched the videos carefully and here are my initial thoughts:

Please take a look at the "bg_only_react" video. Notice that after you press on "tab 2" (first change to "tab 2"), the view does not change immediately (or maybe it does, but it is fully transparent, as there is no content? - this is likely what happens). This leads to situation where we get this seemingly nice transition w/o effect where content appears on previously empty background after a second. I'm pretty sure, that in case the render is heavy (takes like 500 ms) we'll observe that tab changes nicely, but you still can see content from previous screen for those couple hundreds of ms. So this approach does not solve the initial problem, it mitigates it by accidentally displaying transparent content until React mounts rendered views.

I'll give code remarks & suggestions in separate review

@kkafar
Copy link
Member

kkafar commented Jan 5, 2026

Also from these videos & PR description I do not quite understand impact of setting background colour on UITabBarController.view. The videos only talk about setting it on TabScreenComponentView and inside the react content. Can you describe what's the impact of setting it (background colour) on "main container view"?

Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My current understanding is that with leaving the main container view transparent and setting the background colour for the "TabScreenView" only after first content render we could mitigate the problems pretty nicely?

But would glass effects on tab bar behave nicely in such configuration?

Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code itself looks good. I don't have any bigger remarks. But let's discuss the approach first ☝🏻

@kligarski
Copy link
Contributor Author

Please take a look at the "bg_only_react" video. Notice that after you press on "tab 2" (first change to "tab 2"), the view does not change immediately (or maybe it does, but it is fully transparent, as there is no content? - this is likely what happens). This leads to situation where we get this seemingly nice transition w/o effect where content appears on previously empty background after a second. I'm pretty sure, that in case the render is heavy (takes like 500 ms) we'll observe that tab changes nicely, but you still can see content from previous screen for those couple hundreds of ms. So this approach does not solve the initial problem, it mitigates it by accidentally displaying transparent content until React mounts rendered views.

You're right here. What happens is:

  • config tab starts fading out
  • container background becomes therefore visible
  • tab2 fades in but because its content isn't rendered yet, there is only transparent background (no visual impact here)
  • tab2's content appears after it is rendered & mounted by React

Here is the video with heavy tab2 render:

bg_only_react_heavy.mov

Also from these videos & PR description I do not quite understand impact of setting background colour on UITabBarController.view. The videos only talk about setting it on TabScreenComponentView and inside the react content. Can you describe what's the impact of setting it (background colour) on "main container view"?

This is relevant when we try "bg-react-only" approach with transparent TabScreenComponentViews. Here is the same video as above but with blue background:

bg_react_container_heavy.mov

Also, even if the tab content has been rendered, the container background is visible during the transition. Here is the video (container background is blue as well):

bg_react_container_switch.mov

I haven't tested yet how tab bar appearance adaptation works with each of those approaches but previously having solid background for TabScreenComponentView (it is currently systemBackground) helped mitigate some issues previously (details: #3279).

My current understanding is that with leaving the main container view transparent and setting the background colour for the "TabScreenView" only after first content render we could mitigate the problems pretty nicely?

But would glass effects on tab bar behave nicely in such configuration?

I'm not exactly sure what you mean here. "bg-only-tab"/"bg-tab-and-react" + preload should behave well.

@kligarski kligarski requested a review from kkafar January 13, 2026 12:27
Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good. We must only make sure to coordinate the changes with #3535
Let's wait for that PR first & then adjust the naming here.

export type TabBarControllerMode = 'automatic' | 'tabBar' | 'tabSidebar';

export interface BottomTabsProps extends ViewProps {
export type BottomTabsNativeContainerStyleProps = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's refactor this PR after #3535 is merged.

@kkafar
Copy link
Member

kkafar commented Jan 14, 2026

I've merged #3535. We can rebase / merge main to this PR and proceed here.

@kligarski kligarski force-pushed the @kligarski/handle-tabs-background-color-styling branch from 4961f4c to ccdef34 Compare January 14, 2026 15:27
Copy link
Member

@kkafar kkafar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@kligarski kligarski merged commit 102b6ac into main Jan 14, 2026
9 checks passed
@kligarski kligarski deleted the @kligarski/handle-tabs-background-color-styling branch January 14, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants