diff --git a/docs/docs/docs/guides/usage-with-react-navigation.md b/docs/docs/docs/guides/usage-with-react-navigation.md
index 747c2a3..25e9622 100644
--- a/docs/docs/docs/guides/usage-with-react-navigation.md
+++ b/docs/docs/docs/guides/usage-with-react-navigation.md
@@ -55,6 +55,16 @@ Whether to show labels in tabs. Defaults to true.
Whether to disable page animations between tabs. (iOS only)
+#### `scrollEdgeAppearance`
+
+Describes the appearance attributes for the tabBar to use when an observable scroll view is scrolled to the bottom. (iOS only)
+
+Available options:
+- `default` - uses default background and shadow values.
+- `transparent` - uses transparent background and no shadow.
+- `opaque` - uses set of opaque colors that are appropriate for the current theme
+
+Note: It's recommended to use `transparent` or `opaque` without lazy loading as the tab bar background flashes when a view is rendered lazily.
#### `sidebarAdaptable`
A tab bar style that adapts to each platform. (Apple platforms only)
diff --git a/example/src/App.tsx b/example/src/App.tsx
index 599b6a7..07ffa0f 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -31,6 +31,10 @@ const FourTabsNoAnimations = () => {
return ;
};
+const FourTabsTransparentScrollEdgeAppearance = () => {
+ return ;
+};
+
const examples = [
{ component: ThreeTabs, name: 'Three Tabs' },
{ component: FourTabs, name: 'Four Tabs' },
@@ -42,6 +46,10 @@ const examples = [
screenOptions: { headerShown: false },
},
{ component: FourTabsNoAnimations, name: 'Four Tabs - no animations' },
+ {
+ component: FourTabsTransparentScrollEdgeAppearance,
+ name: 'Four Tabs - Transparent scroll edge appearance',
+ },
{ component: NativeBottomTabs, name: 'Native Bottom Tabs' },
{ component: JSBottomTabs, name: 'JS Bottom Tabs' },
{
diff --git a/example/src/Examples/FourTabs.tsx b/example/src/Examples/FourTabs.tsx
index 45ab147..344cbde 100644
--- a/example/src/Examples/FourTabs.tsx
+++ b/example/src/Examples/FourTabs.tsx
@@ -8,11 +8,13 @@ import { Chat } from '../Screens/Chat';
interface Props {
ignoresTopSafeArea?: boolean;
disablePageAnimations?: boolean;
+ scrollEdgeAppearance?: 'default' | 'opaque' | 'transparent';
}
export default function FourTabs({
ignoresTopSafeArea = false,
disablePageAnimations = false,
+ scrollEdgeAppearance = 'default',
}: Props) {
const [index, setIndex] = useState(0);
const [routes] = useState([
@@ -53,6 +55,7 @@ export default function FourTabs({
ignoresTopSafeArea={ignoresTopSafeArea}
sidebarAdaptable
disablePageAnimations={disablePageAnimations}
+ scrollEdgeAppearance={scrollEdgeAppearance}
navigationState={{ index, routes }}
onIndexChange={setIndex}
renderScene={renderScene}
diff --git a/ios/RCTTabViewViewManager.mm b/ios/RCTTabViewViewManager.mm
index 0127534..e60c896 100644
--- a/ios/RCTTabViewViewManager.mm
+++ b/ios/RCTTabViewViewManager.mm
@@ -31,5 +31,6 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(labeled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(ignoresTopSafeArea, BOOL)
RCT_EXPORT_VIEW_PROPERTY(disablePageAnimations, BOOL)
+RCT_EXPORT_VIEW_PROPERTY(scrollEdgeAppearance, NSString)
@end
diff --git a/ios/TabViewImpl.swift b/ios/TabViewImpl.swift
index f35670d..f0502a4 100644
--- a/ios/TabViewImpl.swift
+++ b/ios/TabViewImpl.swift
@@ -14,6 +14,7 @@ class TabViewProps: ObservableObject {
@Published var labeled: Bool?
@Published var ignoresTopSafeArea: Bool?
@Published var disablePageAnimations: Bool = false
+ @Published var scrollEdgeAppearance: String?
}
/**
@@ -70,16 +71,29 @@ struct TabViewImpl: View {
}
onSelect(newValue)
}
- .onAppear {
+ .onChange(of: props.scrollEdgeAppearance) { newValue in
if #available(iOS 15.0, *) {
- // This causes issues with lazy loading making the TabView background blink.
- let appearance = UITabBarAppearance()
- UITabBar.appearance().scrollEdgeAppearance = appearance
+ UITabBar.appearance().scrollEdgeAppearance = configureAppearance(for: newValue ?? "")
}
}
}
}
+private func configureAppearance(for appearanceType: String) -> UITabBarAppearance {
+ let appearance = UITabBarAppearance()
+
+ switch appearanceType {
+ case "opaque":
+ appearance.configureWithOpaqueBackground()
+ case "transparent":
+ appearance.configureWithTransparentBackground()
+ default:
+ appearance.configureWithDefaultBackground()
+ }
+
+ return appearance
+}
+
struct TabItem: View {
var title: String?
var icon: UIImage?
diff --git a/ios/TabViewProvider.swift b/ios/TabViewProvider.swift
index 428df86..ead7613 100644
--- a/ios/TabViewProvider.swift
+++ b/ios/TabViewProvider.swift
@@ -59,6 +59,12 @@ struct TabData: Codable {
}
}
+ @objc var scrollEdgeAppearance: NSString? {
+ didSet {
+ props.scrollEdgeAppearance = scrollEdgeAppearance as? String
+ }
+ }
+
@objc var items: NSArray? {
didSet {
props.items = parseTabData(from: items)
diff --git a/src/TabView.tsx b/src/TabView.tsx
index 99dbc2f..6c30e50 100644
--- a/src/TabView.tsx
+++ b/src/TabView.tsx
@@ -36,6 +36,10 @@ interface Props {
* Whether to disable page animations between tabs. (iOS only)
*/
disablePageAnimations?: boolean;
+ /**
+ * Describes the appearance attributes for the tabBar to use when an observable scroll view is scrolled to the bottom. (iOS only)
+ */
+ scrollEdgeAppearance?: 'default' | 'opaque' | 'transparent';
/**
* State for the tab view.
*
diff --git a/src/TabViewNativeComponent.ts b/src/TabViewNativeComponent.ts
index 358575c..e15681b 100644
--- a/src/TabViewNativeComponent.ts
+++ b/src/TabViewNativeComponent.ts
@@ -22,6 +22,7 @@ export interface TabViewProps extends ViewProps {
icons?: ReadonlyArray;
labeled?: boolean;
sidebarAdaptable?: boolean;
+ scrollEdgeAppearance?: string;
}
export default codegenNativeComponent('RCTTabView');