Closed ghost closed 7 years ago
I experienced this as well to some degree. My setup was a little different. My nested tabs were the first screen in a stack navigator. If I changed the first screen to a normal view everything showed up properly but if the first screen was a tab navigator the view wouldn't show up.
Same here. Only with Android.
So it looks like when I add:
animationEnabled: false,
swipeEnabled: false
to my root navigator the inner tab views show up, but the inner tabs don't swipe like normal (or even when I use the Android style tabs on iOS) and clicking the inner tabs doesn't change the view. Here's an example I made modifying one of Facebook's examples using react-native-material-bottom-navigation
& react-native-detect-navbar-android
. In iOS it works fine.
import React, { Component } from 'react';
import {
Button,
Platform,
ScrollView,
StatusBar
} from 'react-native';
import {
StackNavigator,
TabNavigator,
} from 'react-navigation';
import { NavigationComponent } from 'react-native-material-bottom-navigation';
import { DetectNavbar } from 'react-native-detect-navbar-android';
import Ionicons from 'react-native-vector-icons/Ionicons';
import SampleText from './sample-txt';
const MyNavScreen = ({ navigation, banner }) => (
<ScrollView>
<SampleText>{banner}</SampleText>
<Button
onPress={() => navigation.navigate('Profile', { name: 'Jordan' })}
title="Go to a profile screen"
/>
<Button
onPress={() => navigation.navigate('NotifSettings')}
title="Go to notification settings"
/>
<Button
onPress={() => navigation.navigate('SettingsTab')}
title="Go to settings"
/>
<Button
onPress={() => navigation.goBack(null)}
title="Go back"
/>
</ScrollView>
);
const MyHomeScreen = ({ navigation }) => (
<MyNavScreen
banner="Home Screen"
navigation={navigation}
/>
);
const MyHomeScreen2 = ({ navigation }) => (
<MyNavScreen
banner="Home Screen"
navigation={navigation}
/>
);
const MyProfileScreen = ({ navigation }) => (
<MyNavScreen
banner={`${navigation.state.params.name}s Profile`}
navigation={navigation}
/>
);
MyProfileScreen.navigationOptions = ({ navigation }) => ({
title: `${navigation.state.params.name}'s Profile!`,
});
const MyNotificationsSettingsScreen = ({ navigation }) => (
<MyNavScreen
banner="Notification Settings"
navigation={navigation}
/>
);
const MySettingsScreen = ({ navigation }) => (
<MyNavScreen
banner="Settings"
navigation={navigation}
/>
);
const stackConfig = {};
if (Platform.OS === 'android') {
stackConfig = {
navigationOptions: {
headerStyle: {
paddingTop: StatusBar.currentHeight,
height: 56 + StatusBar.currentHeight,
elevation: 0
}
}
};
}
const HomeTabs = {
HomeTabOne: {
screen: MyHomeScreen,
},
HomeTabTwo: {
screen: MyHomeScreen2,
}
};
const mainTabConfig = {
...TabNavigator.Presets.AndroidTopTabs,
animationEnabled: false,
swipeEnabled: true,
}
const MainTab = StackNavigator({
Home: {
screen: TabNavigator(HomeTabs, mainTabConfig),
path: '/',
navigationOptions: {
title: 'Welcome',
// headerMode: 'none'
},
},
Profile: {
screen: MyProfileScreen,
path: '/people/:name',
navigationOptions: ({ navigation }) => ({
title: `${navigation.state.params.name}'s Profile!`,
}),
},
}, stackConfig);
const SettingsTab = StackNavigator({
Settings: {
screen: MySettingsScreen,
path: '/',
navigationOptions: () => ({
title: 'Settings',
}),
},
NotifSettings: {
screen: MyNotificationsSettingsScreen,
navigationOptions: {
title: 'Notification Settings',
},
},
}, stackConfig);
class StacksInTabs extends Component {
constructor (props) {
super(props);
this.state = { softKeys: false }
}
componentDidMount () {
if (Platform.OS === 'android') {
DetectNavbar.hasSoftKeys().then((softKeys) => {
this.setState({ softKeys });
});
}
}
render () {
let tabBarConfig = {
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
};
if (Platform.OS === 'android') {
tabBarConfig.tabBarComponent = NavigationComponent;
tabBarConfig.tabBarOptions = {
bottomNavigationOptions: {
style: {
height: this.state.softKeys ? 104 : 56
},
innerStyle: {
paddingBottom: this.state.softKeys ? 48 : 0
},
}
}
}
const Tabs = TabNavigator({
MainTab: {
screen: MainTab,
path: '/',
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-home' : 'ios-home-outline'}
size={26}
style={{ color: tintColor }}
/>
),
},
},
SettingsTab: {
screen: SettingsTab,
path: '/settings',
navigationOptions: {
tabBarLabel: 'Settings',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-settings' : 'ios-settings-outline'}
size={26}
style={{ color: tintColor }}
/>
),
},
},
}, tabBarConfig);
return <Tabs />
}
}
export default StacksInTabs;
I had a similar issue, I fixed it by making sure my containers were either the height of the device or a flex:1, have you given this a shot?
adding lazy: true to the TabNavigatorConfig fix this issue
here is my full AppNavigator
import React from 'react';
import { StackNavigator,TabNavigator } from 'react-navigation';
import Screen1 from './screens/Screen1'
import Screen2 from './screens/Screen2'
import Screen3 from './screens/Screen3'
import Screen21 from './screens/Screen21'
import Screen22 from './screens/Screen22'
const Tab2 = TabNavigator ({
Screen2: { screen: Screen2 },
Screen21: { screen: Screen21 },
Screen22: { screen: Screen22 }
})
const Tab1 = TabNavigator ({
Screen1: { screen: Screen1 },
Screen2: { screen: Tab2 },
Screen3:{ screen: Screen3 }
}, {
tabBarPosition: 'bottom',
lazy: true /*Hey look at here Lazy is true*/
});
const AppNavigator = StackNavigator({
Tab1: { screen: Tab1 }
});
export default AppNavigator;
@dabit3 thanks mate it worked for me!!
I think that the first navigator must be stack navigator, though, nesting tab navigators worked for me on iOS, but not on Android. So probably both ways (stack + tab & tab + tab) should work, but I couldn't make it work when Tab + Tab is used.
The way I overcame this was a hack but works...
componentDidMount() { setTimeout(() => { this.refs.scrollView.scrollTo({ x: 0, y: 1, animated: false }) }, 100) }
where you do a timeout after mount and scroll
The @sebringj solution worked for me. My problem only occurs on iOS. I have a ListView inside the Tab, if I do Scroll manually or programmatically the content appears.
@sebringj I had the exact same problem. I used https://github.com/react-community/react-navigation/issues/1238#issuecomment-297213802
Sorry, I did not come back here to mention, but after some tests I set up the removeClippedSubviews
to switch between true
and false
.
When the DataSource updates:
this.setState({ removeClippedSubviews: false });
When the user starts the scroll.
this.setState({ removeClippedSubviews: true });
So I can maintain a good performance with the list.
Hi! In an effort to get the hundreds of issues on this repo under control I'm closing issues tagged as questions. Please don't take this personally - it's simply something we need to do to get the issues to a manageable point. If you still have a question I encourage you to re-read the docs, ask on StackOverflow, or ask on the #react-navigation Reactiflux channel. Thank you!
solved!, dont use View Tag!
blank screen (before solved):
import { TabNavigator } from 'react-navigation';
const Navigator = TabNavigator({
Card: {
screen: Card
},
List: {
screen: Lists
}
});
export default class App extends Component<{}> {
render() {
return (
<View>
<Navigator/>
</View>
);
}
}
SOLVED ! :
import { TabNavigator } from 'react-navigation';
const Navigator = TabNavigator({
Card: {
screen: Card
},
List: {
screen: Lists
}
});
export default class App extends Component<{}> {
render() {
return (
<Navigator/>
);
}
}
This is what i am using.. yet i couldn't fix this issue on android!
import React, { Component } from 'react';
import { View, ScrollView, StatusBar } from 'react-native';
import ImageSlider from 'react-native-image-slider';
import { MainTabNavigator } from './config/routes';
import { STATUS_BAR_HEIGHT } from './constants';
import Header from './components/header';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
position: 0,
interval: null
};
}
componentWillMount() {
this.setState({ interval: setInterval(() => {
this.setState({ position: this.state.position === 3 ? 0 : this.state.position + 1 });
}, 2000) });
}
componentWillUnmount() {
clearInterval(this.state.interval);
}
render() {
return (
<ScrollView style={styles.scrollContainer}>
<StatusBar
backgroundColor="#000"
barStyle="dark-content"
translucent={false}
/>
<Header />
<View style={styles.imageContainer}>
<ImageSlider
images={[
'http://placeimg.com/640/480/any',
'http://placeimg.com/640/480/any',
'http://placeimg.com/640/480/any',
'https://images.pexels.com/photos/216355/pexels-photo-216355.jpeg?w=940&h=650&auto=compress&cs=tinysrgb',
]}
position={this.state.position}
onPositionChanged={position => this.setState({ position })}
/>
</View>
<MainTabNavigator />
</ScrollView>
);
}
}
const styles = {
scrollContainer: {
flex: 1,
marginTop: STATUS_BAR_HEIGHT
},
navContainer: {
flex: 1,
},
imageContainer: {
flex: 1,
flexDirection: 'row',
alignItems: 'stretch'
},
};
routes
import { StackNavigator, TabNavigator, TabBarTop } from 'react-navigation';
import HomeScreen from '../screens/HomeScreen';
export const MainNavigator = StackNavigator({
Home: {
screen: HomeScreen,
}
});
export const MainTabNavigator = TabNavigator({
Home: {
screen: HomeScreen,
navigationOptions: () => ({
tabBarLabel: 'Browse',
})
},
Store: {
screen: HomeScreen,
},
Profile: {
screen: HomeScreen,
}
}, {
initialRouteName: 'Home',
tabBarPosition: 'top',
swipeEnabled: true,
tabBarComponent: TabBarTop,
tabBarOptions: {
allowFontScaling: false,
style: {
backgroundColor: 'red',
padding: 8,
},
labelStyle: {
color: 'white',
fontSize: 12,
},
indicatorStyle: {
borderBottomColor: '#ffffff',
borderBottomWidth: 3,
},
}
});
just fixed using contentContainerStyle={{ flex: 1 }}
in scrollView
Hey! Did anyone solve this issue?
I have the same issue by stacking stack navigators and only one tab based navigator. The issue appears very randomly....
Setting lazy true on the TabNavigator did the trick for me, but the bug only appears when i hide the tabBar on the nested navigator... Really weird
For me the issue is that I have the TabNavigator inside a ScrollView.
EDIT : Annoyingly after trying many things like @keeleycarrigan has mentioned setting both swipeEnabled and animationEnabled to false makes work on both platforms equally.
I had an issue on Android with nested navigators interestingly only on release builds. My TabNavigator was nested in a StackNavigator. Tab A mounted correctly, but Tab B and Tab C never called render()
, meaning that these screens never even mounted when I navigated to them, I obviously only got blank screens. I managed to solve the issue with adding an extra screen that returns <TabNavigator screenProps={{ rootNavigation: navigation }} />
instead of using TabNavigator itself as a a screen like : screen: MainTabNavigator
. It works fine even without using swipeEnabled: false, animationEnabled: false, lazyLoad: true
in my MainTabNavigator
.
Package versions:
"react": "16.2.0",
"react-native": "0.52",
"react-navigation": "1.1.2",
My setup looks like this:
Top level StackNavigator
export default StackNavigator(
{
Splash: { screen: SplashScreen, path: 'Splash' },
Login: { screen: LoginScreen, path: 'Login' },
// Home: { screen: MainTabNavigator, path: 'Home' }, -> replace this line with next line
Home: { screen: HomeScreen, path: 'Home' }, // prevent nested navigator bugs
WebView: { screen: WebViewScreen, path: 'WebViewCards' },
SubscriptionDetails: { screen: SubscriptionDetailsScreen, path: 'SubscriptionDetails' },
},
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
},
},
);
MainTabNavigator
export const MainTabNavigator = TabNavigator({
MainCards: { screen: cardsNavigator }, // stack navigator
MainCollections: { screen: collectionsNavigator }, // stack navigator
Profile: { screen: profileNavigator }, // stack navigator
}, {
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: Platform.OS === 'android' ? colors.greySuperdark : colors.iOSBlue,
inactiveTintColor: colors.greySuperdark,
style: { backgroundColor: 'white' },
},
});
create HomeScreen
after replacing screen: MainTabNavigator
with screen: HomeScreen
HomeScreen
import React, { Component } from 'react';
import { MainTabNavigator } from './location/to/file';
export default class HomeScreen extends Component {
static navigationOptions = ({ navigation }) => {
return {
title: 'Home',
headerStyle: {
backgroundColor: 'white',
},
headerBackTitle: null,
};
};
render() {
const { navigation } = this.props;
return <MainTabNavigator screenProps={{ rootNavigation: navigation }} />;
}
}
I don't like to spend more time on investigating the cause of this behaviour, I hope this workaround helps out somebody, I use several more nested TabNavigators this way and all of them are working fine. :)
After playing around with countless permutations of seemingly unrelated config settings, here's how I fixed the blank tabs issue:
const TabBar = TabNavigator(
{
Tab1: { screen: Tab1 },
Tab2: { screen: Tab2 },
},
{
swipeEnabled: true, // fixes a bug in react navigation
lazy: false, // fixes a bug in react navigation
}
);
Solution from @robvolk seems to fix the blank tab screen for me as well. I'm using 1.2.0. swipeEnabled: true & lazy: false must be specify.
@robvolk thanks for experimenting, it indeed solves the problem on v1.1.2.
Only way for me to fix it is to downgrade to 1.0.0-beta15. It occurs with RTL enabled.
npm i react-navigation@1.0.0-beta.15
@spencercarli reopen this issue and set label bug
.
@Gentlee - can you create a new issue that follows the issue template and describes the problem concisely? I would be happy to look at it if so!
If you're working with redux, the issue might be about correctly applying the middleware. I for one did create it using
createReactNavigationReduxMiddleware(
'root',
state => state.nav,
);
But I never applied it to my store! Hence your code for the store should look something like:
const navMiddleware = createReactNavigationReduxMiddleware(
'root',
state => state.nav,
);
const addListener = createReduxBoundAddListener('root');
const store = createStore(
rootReducer,
applyMiddleware(navMiddleware)
);
Simply applying the middleware fixed the issue for me, no need to set lazy: false
and swipeEnabled: true
anymore (although that technique worked as well for me)
@robvolk thank you!!! Setting lazy:false and swipeEnabled:true solved my issue. I wish I had read your notes exactly 3 hours ago!
As @AntoineChwat indicates it's probably due to a misconfiguration of Redux middleware. I returned the incorrect state sub property in the second argument of createReactNavigationReduxMiddleware
.
@f4z3k4s many thanks your solution works with me
Solved this problem using a combination of @gananggww and @Chathula's recommendations:
Navigation
component is nested within a ScrollView
(not View
)contentContainerStyle={{ flex: 1 }}
to your ScrollView
@robvolk solution worked for me but what if i really want to disable swipe?
@robvolk solution worked for me but what if i really want to disable swipe?
Since v2.x is out, I'd try upgrading and see if the problem has been fixed. I've removed tabs from my UI for unrelated reasons, so I can't say for sure.
I had a similar issue, I fixed it by making sure my containers were either the height of the device or a flex:1, have you given this a shot?
this worked for me
on App.js const styles = StyleSheet.create({ container: { flex:1, },
I had a similar error with Expo SDK 44 and and outdated react-native 0.64.1 - after upgrading to 0.66.4 the Stack Screens appears.
Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.
I had a similar error with Expo SDK 44 and and outdated react-native 0.64.1 - after upgrading to 0.66.4 the Stack Screens appears.
I'm using EXPO SDK 43, this works for me! Thank you good man.
Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.
Current Behavior
Screens' contents are not shown / the screens are blank.
Expected Behavior
Should see the Screen's contents
Your Environment
This is my navigator structure
The screen is blank when I navigate to "Main", in there I also cannot switch between the Grid and Review tabs.