diff --git a/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm b/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm index 92cab0e..084c2d8 100644 --- a/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm +++ b/packages/react-native-bottom-tabs/ios/RCTTabViewComponentView.mm @@ -180,6 +180,9 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & _tabViewProvider.tabBarHidden = newViewProps.tabBarHidden; } + if (oldViewProps.ignoresContentBackground != newViewProps.ignoresContentBackground) { + _tabViewProvider.ignoresContentBackground = newViewProps.ignoresContentBackground; + } [super updateProps:props oldProps:oldProps]; } diff --git a/packages/react-native-bottom-tabs/ios/TabViewImpl.swift b/packages/react-native-bottom-tabs/ios/TabViewImpl.swift index 72938be..4c4c88f 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewImpl.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewImpl.swift @@ -45,6 +45,7 @@ struct TabViewImpl: View { var body: some View { tabContent .tabBarMinimizeBehavior(props.minimizeBehavior) + .ignoresContentBackground(props.ignoresContentBackground, barTintColor: props.barTintColor) #if !os(tvOS) && !os(macOS) && !os(visionOS) .onTabItemEvent { index, isLongPress in let item = props.filteredItems[safe: index] @@ -325,4 +326,26 @@ extension View { self } } + + /// Disables iOS 26 liquid glass content sampling and uses a solid background instead. + /// When enabled, the tab bar will use the specified barTintColor (or system default if nil) + /// instead of dynamically sampling colors from the content behind it. + @ViewBuilder + func ignoresContentBackground(_ ignores: Bool, barTintColor: PlatformColor?) -> some View { + #if compiler(>=6.2) + if #available(iOS 26.0, *) { + if ignores { + self + .toolbarBackgroundVisibility(.visible, for: .tabBar) + .toolbarBackground(barTintColor.map { Color($0) } ?? Color(.systemBackground), for: .tabBar) + } else { + self + } + } else { + self + } + #else + self + #endif + } } diff --git a/packages/react-native-bottom-tabs/ios/TabViewProps.swift b/packages/react-native-bottom-tabs/ios/TabViewProps.swift index 9cfb29a..a9edfc7 100644 --- a/packages/react-native-bottom-tabs/ios/TabViewProps.swift +++ b/packages/react-native-bottom-tabs/ios/TabViewProps.swift @@ -71,6 +71,7 @@ class TabViewProps: ObservableObject { @Published var fontFamily: String? @Published var fontWeight: String? @Published var tabBarHidden: Bool = false + @Published var ignoresContentBackground: Bool = false var selectedActiveTintColor: PlatformColor? { if let selectedPage, diff --git a/packages/react-native-bottom-tabs/src/TabView.tsx b/packages/react-native-bottom-tabs/src/TabView.tsx index 4e93f09..e98ed9f 100644 --- a/packages/react-native-bottom-tabs/src/TabView.tsx +++ b/packages/react-native-bottom-tabs/src/TabView.tsx @@ -212,6 +212,18 @@ interface Props { * @default 'locale' */ layoutDirection?: LayoutDirection; + /** + * When true, disables iOS 26 liquid glass content sampling and uses a solid + * background color (from tabBarStyle.backgroundColor) instead of dynamically + * sampling colors from the content behind the tab bar. (iOS 26+ only) + * + * Use this when you have dynamic content (like maps) where the liquid glass + * effect causes the tab bar to have inconsistent or unreadable colors. + * + * @platform ios + * @default false + */ + ignoresContentBackground?: boolean; } const ANDROID_MAX_TABS = 100; diff --git a/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts b/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts index 50082c5..3aa3b18 100644 --- a/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts +++ b/packages/react-native-bottom-tabs/src/TabViewNativeComponent.ts @@ -61,6 +61,7 @@ export interface TabViewProps extends ViewProps { fontFamily?: string; fontWeight?: string; fontSize?: Int32; + ignoresContentBackground?: boolean; } export default codegenNativeComponent('RNCTabView', {