callstack / callstack/react-native-bottom-tabs
tabBarMinimizeBehavior: 'onScrollDown' not working on iOS 26+ with nested Stack Navigator
- Dominant language
- TypeScript
- Stars
- 1.5k
- Forks
- 109
- Avg merge
- 11h 44m
- Merged PRs (30d)
- 8
Description
### Before submitting a new issue
- [x] I tested using the latest version of the library, as the bug might be already fixed.
- [x] I tested using a [supported version](https://github.com/reactwg/react-native-releases/blob/main/docs/support.md) of react native.
- [x] I checked for possible duplicate issues, with possible answers.
### Bug summary
### Description
The `tabBarMinimizeBehavior: 'onScrollDown'` option is not working when using `createNativeBottomTabNavigator` with nested `NativeStackNavigator` screens on iOS 26+.
### Environment
- **React Native version:** 0.82.1
- **@react-navigation/bottom-tabs version:** 7.9.0
- **react-native-screens version:** 4.18.0
- **iOS version:** 26.0+
- **Platform:** iOS (iPhone)
### Steps to Reproduce
1. Create a `NativeBottomTabNavigator` with `tabBarMinimizeBehavior: 'onScrollDown'` and `tabBarControllerMode: 'tabSidebar'`
2. Use nested `NativeStackNavigator` as screen components (e.g., `HomeStack` containing `HomeScreen`)
3. Inside the nested screen, use a `ScrollView` with `contentInsetAdjustmentBehavior="automatic"`
4. Scroll down in the ScrollView
5. Tab bar does not minimize
### Expected Behavior
When scrolling down, the tab bar should minimize (collapse to show only the active tab on the left side) as per iOS 26's native behavior.
### Actual Behavior
The tab bar remains fully visible and does not minimize when scrolling down.
### Code Example
// TabStack.tsx
const NativeTab = createNativeBottomTabNavigator();
export const TabStack = () => {
const [isIOS26Plus, setIsIOS26Plus] = useState(false);
useEffect(() => {
if (Platform.OS === 'ios') {
const iosVersion = parseFloat(DeviceInfo.getSystemVersion());
setIsIOS26Plus(iosVersion >= 26.0);
}
}, []);
return (
({
lazy: false,
headerShown: false,
...(isIOS26Plus && {
tabBarMinimizeBehavior: 'onScrollDown',
tabBarControllerMode: 'tabSidebar',
}),
})}
>
);
};
// HomeStack.tsx
const Stack = createNativeStackNavigator();
export const HomeStack = () => {
return (
);
};
// HomeView.tsx (inside HomeScreen)
{/* Scrollable content */}
### Additional Context
- The issue occurs specifically with nested navigators (NativeTab → NativeStack → Screen)
- Works correctly when using direct screen components without nesting
- `contentInsetAdjustmentBehavior="automatic"` is set on the ScrollView as per documentation
- `tabBarControllerMode: 'tabSidebar'` is also set
- Tested on iOS 26.0+ devices/simulators
### Possible Related Issues
- The scroll detection might not be propagating correctly through nested navigators
- NativeTab might need direct access to the ScrollView to detect scroll events
### Library version
7.9.0
### Environment info
```shell
info Fetching system and libraries information...
System:
OS: macOS 26.2
CPU: (12) arm64 Apple M3 Pro
Memory: 205.39 MB / 36.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.9.0
path: /Users/emirbayir/.nvm/versions/node/v22.9.0/bin/node
Yarn:
version: 3.6.4
path: /opt/homebrew/bin/yarn
npm:
version: 11.6.2
path: /Users/emirbayir/.nvm/versions/node/v22.9.0/bin/npm
Watchman:
version: 2025.10.06.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.15.2
path: /Users/emirbayir/.rvm/gems/ruby-3.2.0/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.2
- iOS 26.2
- macOS 26.2
- tvOS 26.2
- visionOS 26.2
- watchOS 26.2
Android SDK:
API Levels:
- "33"
- "34"
- "35"
- "36"
Build Tools:
- 30.0.3
- 33.0.0
- 33.0.1
- 34.0.0
- 35.0.0
- 36.0.0
- 36.1.0
System Images:
- android-30 | Google APIs ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
- android-35 | Pre-Release 16 KB Page Size Google Play ARM 64 v8a
- android-36 | Google Play ARM 64 v8a
- android-VanillaIceCream | Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2025.1 AI-251.26094.121.2513.14007798
Xcode:
version: 26.2/17C52
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.16
path: /usr/bin/javac
Ruby:
version: 3.2.0
path: /Users/emirbayir/.rvm/rubies/ruby-3.2.0/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.0.0
wanted: 20.0.0
react:
installed: 19.1.1
wanted: 19.1.1
react-native:
installed: 0.82.1
wanted: ^0.82.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
info React Native v0.83.0 is now available (your project is running on v0.82.1).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.83.0
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.82.1&to=0.83.0
info For more info, check out "https://reactnative.dev/docs/upgrading?os=macos".
```
### Steps to reproduce
1. …
2. …
### Reproducible sample code
```js
### Steps to Reproduce
1. **Create a new React Native project:**
npx react-native@0.82.1 init TestNativeTabMinimize
cd TestNativeTabMinimize
2. **Install required dependencies:**ash
npm install @react-navigation/bottom-tabs@7.9.0 @react-navigation/native@7.1.18 @react-navigation/native-stack@7.5.0 react-native-screens@4.18.0 react-native-safe-area-context@5.6.2 react-native-device-info@14.1.1
3. **For iOS, install pods:**
cd ios && pod install && cd ..
4. **Create the following files:**
**App.tsx:**
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { TabStack } from './src/navigation/TabStack';
export default function App() {
return (
);
}
**src/navigation/TabStack.tsx:**
import React, { useEffect, useState } from 'react';
import { createNativeBottomTabNavigator } from '@react-navigation/bottom-tabs/unstable';
import { Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';
import { HomeStack } from './HomeStack';
import { ProfileStack } from './ProfileStack';
const NativeTab = createNativeBottomTabNavigator();
export const TabStack = () => {
const [isIOS26Plus, setIsIOS26Plus] = useState(false);
useEffect(() => {
if (Platform.OS === 'ios') {
const iosVersion = parseFloat(DeviceInfo.getSystemVersion());
setIsIOS26Plus(iosVersion >= 26.0);
}
}, []);
return (
({
headerShown: false,
...(isIOS26Plus && {
tabBarMinimizeBehavior: 'onScrollDown',
tabBarControllerMode: 'tabSidebar',
}),
})}
>
);
};
**src/navigation/HomeStack.tsx:**
import React from 'react';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { HomeScreen } from '../screens/HomeScreen';
const Stack = createNativeStackNavigator();
export const HomeStack = () => {
return (
);
};
**src/navigation/ProfileStack.tsx:**
import React from 'react';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { ProfileScreen } from '../screens/ProfileScreen';
const Stack = createNativeStackNavigator();
export const ProfileStack = () => {
return (
);
};
**src/screens/HomeScreen.tsx:**sx
import React from 'react';
import { View, ScrollView, Text, StyleSheet, Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';
export const HomeScreen = () => {
const isIOS26Plus = Platform.OS === 'ios' && parseFloat(DeviceInfo.getSystemVersion()) >= 26.0;
return (
{Array.from({ length: 50 }, (_, i) => (
Item {i + 1}
))}
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
scrollView: {
flex: 1,
},
contentContainer: {
padding: 20,
paddingBottom: 100,
},
item: {
padding: 20,
marginBottom: 10,
backgroundColor: '#f0f0f0',
borderRadius: 8,
},
text: {
fontSize: 16,
},
});
**src/screens/ProfileScreen.tsx:**
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export const ProfileScreen = () => {
return (
Profile Screen
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
text: {
fontSize: 24,
},
});
5. **Update index.js:**
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
AppRegistry.registerComponent(appName, () => App);
6. **Run the app:**
# iOS
npx react-native run-ios
# Or specify iOS 26+ simulator if available
npx react-native run-ios --simulator="iPhone 16 Pro (iOS 26.0)"
7. **Test the behavior:**
- Navigate to the "Home" tab
- Scroll down in the ScrollView
- **Expected:** Tab bar should minimize (collapse to show only active tab on left)
- **Actual:** Tab bar remains fully visible
### Platform
- **iOS:** ✅ Issue occurs
- **Android:** ❌ Not applicable (feature is iOS 26+ only)
### Test Environment
- **Simulator:** iPhone 16 Pro (iOS 26.0) or any iOS 26+ simulator
- **Physical Device:** Any iPhone running iOS 26.0 or later
- **React Native:** 0.82.1
- **@react-navigation/bottom-tabs:** 7.9.0
- **react-native-screens:** 4.18.0
### Additional Notes
- The issue only occurs when using **nested navigators** (NativeTab → NativeStack → Screen)
- If you use direct screen components without nesting, the minimize behavior works correctly
- The `contentInsetAdjustmentBehavior="automatic"` is set on the ScrollView as per documentation requirements
- `tabBarControllerMode: 'tabSidebar'` is also configured
### Minimal Reproduction Repository
[Link to GitHub repository with minimal reproduction code - if you create one]
```
Contributor guide
Assessment
This issue has not been assessed yet.