How can I hide the screen header but show my back button? - react-native

I would like to hide my screen header but still show the back button in my Stack Navigator? I have set screenOptions={{ headerShown: false }} in my Stack.Navigator, which hides both the screen header and back button. I would like to just hide the screen header.
Can someone please assist with this? Below is my Stack Navigator:
function SearchStack() {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="SearchScreen" component={SearchScreen} />
<Stack.Screen name="SearchListScreen" component={SearchListScreen} />
</Stack.Navigator>
);
}
In the tab navigator the stack is set as:
<Tab.Navigator screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {...})}>
<Tab.Screen name="Search" component={SearchStack} />
</Tab.Navigator>
This is what I'm currently seeing:
But this is what I would like to have with my Tab navigation bar still at the bottom for the search stack:
This is what I get using options={{headerMode:"none"}} in Stack.Navigator:
The below occurs when adding updating the Stack.Navigator to <Stack.Navigator screenOptions={{ headerTitle:"", headerTransparent:true }}> . How can add or move the back button to the top exactly like the 2nd image, which is achieved when not adding the Stack to the Tab.Screen so changing:
<Tab.Screen name="Search" component={SearchStack} />
to
<Tab.Screen name="Search" component={SearchScreen} />
but doing this causes the tab to not appear in the Search list screen.

The back button is part of the header, so you can't hide the header and keep the back button.
What you want to do is to hide other parts of the header except for the back button, which would be
Title, with headerTitle: ""
Background, with headerTransparent: true

for hide the back button in react-native, we can use property,
headerBackVisible:false this property only work on android
<Stack.Screen
options={{headerBackVisible: false}}
/>

example use of in Stack
const CustomerStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="First"
component={First}
options={{headerShown: false}}
/>
<Stack.Screen
name="Third"
component={Third}
options={{headerTitle: '', headerTransparent: true}}
/>
</Stack.Navigator>
);
}

If you don't want the default header then use like this
screenOptions={{ headerShown: false }}
and write custom code for the header with back button in your component
(If your are using class component) Then
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> </TouchableOpacity>
if you want header title too then,
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> <Text>SearchListScren</Text> </TouchableOpacity>
Put this code at top of the component code under a container

Related

Render a nested Tab screen in a Stack Navigator

Seems it should be so simple but I can't figure it out. I have a nested Tab Navigator inside a Stack Navigator like so:
function App(){
const Main = () =>{
<Tab.Navigator initialRouteName={"Players"}>
<Tab.Screen name="Players" component={FindPlayers} />
<Tab.Screen name="Requests" component={MatchRequests} />
</Tab.Navigator>
}
....
return (
<NavigationContainer>
<Stack.Navigator initialRouteName={"Main"} >
<Stack.Screen name="Main" component={Main}/>
<Stack.Screen name="CourtPicker" component={CourtPicker}/>
</Stack.Navigator>
</NavigationContainer>
)}
It renders a blank screen with the Header that says "Main" instead of rendering the FindPlayers component.
My expectation is that I've defined an initial route Main which should render my Main component which is a Tab navigator, which should in turn render the Players component because I've defined the initialRouteName as such.
What am I doing wrong here?
according to Nesting navigators
Try :
<Stack.Screen name="Main" component={Main} options={{
headerShown: false,
}}/>

Floating navigation button for stack navigator

I've got a stack navigator for create item flow and I wanted to have a floating button at the bottom, which wouldn't be affected by the screen transitions, so I ended up placing it on the same level as that stack navigator, just like that:
<>
<Stack.Navigator screenOptions={{ headerShown: true }}>
<Stack.Screen name="Route1" component={Component1} />
<Stack.Screen name="Route2" component={Component2} />
<Stack.Screen name="Route3" component={Component3} />
</Stack.Navigator>
<Button.Primary
onPress={() => {
navigate(SCREENS[currentStep]);
}}
>
Continue
</Button.Primary>
</>
Is that a good solution, or is there a cleaner approach? I don't like that, because it's going to require mixing navigation logic with other things, such as requesting something from the api.

How to minimize React Native Navigation Modal?

How to minimize a modal within a Stack Navigator in React Native so that the model still shows as a small bar at the bottom of the screen and stays even when switching tabs (like in the pictures I attached).
Picture of Modal opened
Picture of Modal miminized
Currently I have built a Bottom Navigation Tab Bar and within this Tab Navigator I have a Stack Navigator where the Modal can be opened.
<Tab.Navigator initialRouteName="Session">
<Tab.Screen name="Social">{() => <Social />}</Tab.Screen>
<Tab.Screen name="History">{() => <History />}</Tab.Screen>
<Tab.Screen name="Session" options={{headerShown: false}}>
{() => (
<Stack.Navigator>
<Stack.Screen name="Start Session">
{() => <StartSession navigate={navigate} />}
</Stack.Screen>
<Stack.Screen
name="New Template"
options={{
presentation: 'containedModal',
}}>
{() => <AddTemplate />}
</Stack.Screen>
</Stack.Navigator>
)}
</Tab.Screen>
<Tab.Screen name="Activities">{() => <Activities />}</Tab.Screen>
<Tab.Screen name="Profile">
{() => <Profile setUser={setUser} setUserCreds={setUserCreds} />}
</Tab.Screen>
</Tab.Navigator>
You can achieve this using a bottom sheet instead of using a modal from react native navigation.
Something like:
https://www.npmjs.com/package/#gorhom/bottom-sheet

Disable animation for a custom header in React Navigation

I would like to disable the screen animation for the header part of the Stack Navigator.
I have a common custom Header defined in the Stack Navigator via screenOptions.
And have default animations for screen transitions.
I want to make sure the animation happens only to the screen and not to my header component.
Since the header will a static content.
I've also tried making the headerMode as screen and float but that did not help.
I wanted to see if there is a property similar to animationEnabled but for the header component.
<Stack.Navigator
screenOptions= {{
headerMode: 'screen',
animation: 'fade',
header: (props) =>
<Header {...props} />
}}>
// Rest of my screens
</Stack.Navigator>
What you could do is completely separate the header from your Navigator, and use a ref to control navigation from it. Something like this:
const App = () => {
const navigationRef = useNavigationContainerRef()
return (
<View>
<Text>This header won't animate!</Text>
<Text onPress={() => navigationRef.navigate('Home')}>Link</Text>
</View>
<NavigationContainer ref={navigationRef}>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Other" component={OtherScreen} />
</Stack.Navigator>
</NavigationContainer>
)
}

Stack.Navigator fade-transition between Stack.Screens in React-native?

How can I add a transition effect to Stacked Screes in React-native?
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Stocks" component={StocksScreen} />
</Stack.Navigator>
</NavigationContainer>
Is there a default way to achieve a fadeIn / fadeOut effect?
The simplest way to achieve fade effect:
const forFade = ({ current }) => ({
cardStyle: {
opacity: current.progress,
},
});
If you want to apply fade effect for the entire navigator:
<Stack.Navigator
screenOptions={{
headerShown: false,
cardStyleInterpolator: forFade,
}}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Stocks" component={StocksScreen} />
</Stack.Navigator>
Also you can apply cardStyleInterpolator for single screen via setting options:
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ cardStyleInterpolator: forFade }}/>
You can customize forFade function in order to achieve other effects, or also you can use some pre-made interpolators, as:
forHorizontalIOS
forVerticalIOS
forModalPresentationIOS
forFadeFromBottomAndroid
forRevealFromBottomAndroid
import { CardStyleInterpolators } from '#react-navigation/stack';
<Stack.Screen
name="Profile"
component={Profile}
options={{
cardStyleInterpolator: CardStyleInterpolators.forFadeFromBottomAndroid,
}}
/>;
More info here: https://reactnavigation.org/docs/stack-navigator/#animations
For React Navigation 6.xx you can use the animation option:
<Stack.Screen
name="Profile"
component={Profile}
options={{ animation: 'fade' }}
/>
Supported values:
"default": use the platform default animation
"fade": fade screen in or out
"flip": flip the screen, requires presentation: "modal" (iOS only)
"simple_push": use the platform default animation, but without shadow and native header transition (iOS only)
"slide_from_bottom": slide in the new screen from bottom
"slide_from_right": slide in the new screen from right (Android only, uses default animation on iOS)
"slide_from_left": slide in the new screen from left (Android only, uses default animation on iOS)
"none": don't animate the screen