How to position back arrow button in react navigation - javascript

I'm new to react-native and I was playing around with react-navigation. I have a problem with positioning of the back-arrow in the navigation tab. I would like to target the back-arrow in order to position it.
Here is what I've done so far
static navigationOptions = ({navigation}) => {
return {
headerTitle: navigation.state.params.navTitle,
headerStyle: {
height: '45%',
backgroundColor: '#ffae19'
},
headerTintColor: 'white',
// this what I tried to implement
headerTitleStyle: { position: 'absolute', top: 10 }
}
}
You see I just need to make the back-arrow positioned at the top, because in my current tab the arrow is at the center of the nav-tab (vertically), which looks ugly. Any help ?

You cannot directly change the style of the automatic back arrow. However, you can override the back arrow with your custom component, as explained on React Navigation docs. The article is about right part of the bar, but as stated in the last part, the same holds for the left part of the bar, where the arrow is placed.
static navigationOptions = ({navigation}) => {
return {
headerTitle: navigation.state.params.navTitle,
headerStyle: {
height: '45%',
backgroundColor: '#ffae19'
},
headerTintColor: 'white',
headerLeft: (
<Button onPress={() => navigation.goBack()} title="Back" />
)
}
}
If you don't like the "Back" label, you can install react-native-vector-icons using npm and modify the previous code like
static navigationOptions = ({navigation}) => {
return {
headerTitle: navigation.state.params.navTitle,
headerStyle: {
height: '45%',
backgroundColor: '#ffae19'
},
headerTintColor: 'white',
headerLeft: (
<TouchableWithoutFeedback
style={{ /* Put your style here */}}
onPress={() => navigation.goBack()} >
>
<Icon name="md-arrow-round-back" size={16} color="#000" />
</TouchableWithoutFeedback>
)
}
}
Don't forget to import icons
import Icon from 'react-native-vector-icons/Ionicons;

Related

how to centering Title Without being affected by headerLeft in react navigation?

I use react navigation and I'm centering the title in the bar but it's affected with headerLeft,
when I turn off them it's work and center the title exactly,
how to do this without affecting the title with another left and right button\icon
code:
const RootNavigator = createStackNavigator({
Home: {
screen: Home,
navigationOptions: {
title: "Home",
//headerLeft: null, // here the issue
headerStyle: {
backgroundColor: 'rgb(42,55,68)',
},
headerTitleStyle: {
flex: 1,
textAlign: 'center',
color: "#fff",
}
}
}
});
No issue with your headerTitleStyle props, just make sure to have a View for both headerLeft and headerRight.
Example:
headerLeft : (<View><Entypo name='menu' size={28} color='white' onPress={() => navigation.openDrawer()} /></View>),
headerRight:(<View></View>)

How to set Background Image in React-navigation header [duplicate]

I'm using react navigation in a react native project and I want to customize the header with an image.
For a color I can use simple styling, but since react native doesn't support background images I need a different solution.
Update:
Since v2 of the library there's an special option for setting the header background, namely headerBackground.
This option accepts a React component, so when set to an Image component, it will use that.
For example:
export default createStackNavigator({
Home: {
screen: HomeScreen
},
}, {
navigationOptions: {
headerBackground: () => (
<Image
style={StyleSheet.absoluteFill}
source={{ uri: 'https://upload.wikimedia.org/wikipedia/commons/3/36/Hopetoun_falls.jpg' }}
/>
),
}
});
Working example: https://snack.expo.io/#koen/react-navigation-header-background
Old answer, for when still using React Navigation v1:
Creating a custom header with an image is actually really simple.
By wrapping the Header with a view and placing an absolute positioned image in that view, the image will scale to its parent size.
Important is to set the backgroundColor of the default header to transparent.
const ImageHeader = props => (
<View style={{ backgroundColor: '#eee' }}>
<Image
style={StyleSheet.absoluteFill}
source={{ uri: 'https://upload.wikimedia.org/wikipedia/commons/3/36/Hopetoun_falls.jpg' }}
/>
<Header {...props} style={{ backgroundColor: 'transparent' }}/>
</View>
);
And then use that component as header:
const SimpleStack = StackNavigator({
Home: {
screen: MyHomeScreen,
},
}, {
navigationOptions: {
headerTitleStyle: { color: '#fff' },
header: (props) => <ImageHeader {...props} />,
}
});
Which would result in:
According to the official docs of react-navigation v5, it can be implemented as follows:
https://reactnavigation.org/docs/headers/#replacing-the-title-with-a-custom-component
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
// title: 'App Name'
options={{
headerTitle: (props) => ( // App Logo
<Image
style={{ width: 200, height: 50 }}
source={require('../assets/images/app-logo-1.png')}
resizeMode='contain'
/>
),
headerTitleStyle: { flex: 1, textAlign: 'center' },
}}
/>
</Stack.Navigator>
Update for React Navigation v5! (making this post for future references)
For react navigation 5, I found this solution.
In StackNavigator.js class you can set a different image for each page (Stack.Screen):
<Stack.Screen
name='Home'
component={HomeScreen}
options={{
title: <Image style={{ width: 250, height: 50 }}
source = require('../images/yourimage.png')}/>
}}
/>
Then, you must adjust width, height, and position of the image, but it works! I think it's the simpliest way. Here's the output (yes, it's my image, before adjustments).
Don't forget to import Image!
import { Image } from 'react-native'

How to render the same component on all screens?

I have a StackNavigator, where I've specified the same headerRight Icon for every screen:
export default StackNavigator(
{
Authorization: {
screen: AuthorizationScreen
},
SignIn: {
screen: SignInScreen
},
SignUp: {
screen: SignUpScreen
},
Main: {
screen: MainScreen
},
Language: {
screen: LanguageScreen
},
//...etc
},
{
navigationOptions: {
headerRight: (
<Icon color={'#77767c'}
name='ios-contact-outline'
size={30}
style={{ paddingRight: 30}}
type='ionicon'
/>
),
}
}
)
All the screens are imported from separate files. When this Icon is pressed, I want the same component to render regardless of what screen I'm on. The problem is, I can't think of a way to do this outside of writing in some kind of state handling and onPress function for every single screen I have, which would be really tedious to write and maintain. Is there any way to get around this and only write the component rendering once?
You can create one component for Header and pass it into all the screen's navigationOptions. Then you just need to handle the method on each screen and you can do your stuff at here.
Custom Header Class:
class Header extends Component {
render() {
const props = this.props;
return (<View>
<View
style={KEEP_YOUR_STYLE}
/>
<View style={styles.containerStyle} >
<Text
style={your_style}
numberOfLines={1}
>TITLE</Text>
<TouchableOpacity
style={styles.touchableOpacityStyle}
onPress={props.onPress}
>
<Image
source={YOUR_ICON}
style={{
position:'absolute',
right: 10,
width: 20,
height: 20,
resizeMode: 'cover',
}
} />}
</TouchableOpacity>
</View>
</View>
);
}
}
export { Header };
In your StackNavigator:
const defaultNavigation = ({ navigation }) => ({
header: (<Header
title='Hellow'
/>),
});
Language: {
screen: LanguageScreen,
navigationOptions: defaultNavigation,
},
In your particular Screen:
static navigationOptions = ({ navigation }) => ({
header: (
<Header
title='Your Title'
onPress={() => {
// DO YOUR STUFF
}}
/>),
});

How to use tabBarComponent for TabNavigator? Tab bar not showing

I'm trying to make my own custom tab bar and it seems tabBarComponent is the way to do it by setting as my own component. With the below code my tab bar does not show up.
const TabNav = TabNavigator({
LaunchScreen: {
screen: PrimaryNav,
navigationOptions: {
tabBarLabel:'Find',
tabBarIcon: ({ tintColor }) => (
<Icon name='search' size={20} color='white' />
),
},
},
}, {
navigationOptions: {
headerTintColor: 'grey'
},
tabBarComponent: FooterTabs,
tabBarPosition: 'bottom',
swipeEnabled:false,
animationEnabled:false,
lazy:true,
tabBarOptions: {
showIcon:true,
showLabel:false,
style: {
backgroundColor: 'black'
}
}
});
In FooterTabs.js:
export default class FooterTabs extends Component {
render () {
return (
<View style={styles.container}>
<Text>FooterTabs Component</Text>
</View>
)
}
}
What am I missing?
const TabNav = TabNavigator({
......,
tabBarComponent: props => (
<FooterTabs{...props} />
),
tabBarPosition: 'bottom',
........
});
Try that. enclose your FooterTabs i.e <FooterTabs /> not FooterTabs
After some trial and error, the solution to my issue was to wrap my footer content in a ScrollView, then the tabs showed up as expected, though I am not sure why that is required.
I also implemented Caleb's suggestion (thanks!) of using tabBarComponent: props => <FooterTabs{...props} /> in order to pass the props which I need though was not the cause of the issue.

React Navigation - Gradient color for Header

I am using React Navigation in React Native app and I want to change the backgroundColor for the header to be gradient and I found out there is a node module : react-native-linear-gradient to achieve gradient in react native.
I have Root StackNavigator like that :
const Router = StackNavigator({
Login: {
screen: Login,
navigationOptions: ({navigation}) => ({
headerTitle: <Text>SomeTitle</Text>
headerLeft: <SearchAndAgent />,
headerRight: <TouchableOpacity
onPress={() => { null }
</TouchableOpacity>,
headerStyle: { backgroundColor: '#005D97' },
}),
},
});
I can wrap Text or View to be gradient like that :
<LinearGradient colors={['#3076A7', '#19398A']}><Text style={styles.title}>{title}</Text></LinearGradient>,
How can I wrap the header background in the navigationOptions to use
the the LinearGradient module?
I know that I can create a custom header component and use it but when I am doing it all the native navigation animations from React Navigation not working like the Title Animation between two Routes so its not helping me.
Thanks for helping !
Just for your information, now with headerBackground props it's a way easier.
You can have a gradient header just doing this :
navigationOptions: {
headerBackground: (
<LinearGradient
colors={['#a13388', '#10356c']}
style={{ flex: 1 }}
start={{x: 0, y: 0}}
end={{x: 1, y: 0}}
/>
),
headerTitleStyle: { color: '#fff' },
}
This solution works good even with SafeArea for IosX
The solution of Mark P was right but now you need to define headerStyle and do the absolute positioning there:
navigationOptions: {
header: props => <GradientHeader {...props} />,
headerStyle: {
backgroundColor: 'transparent',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
},
},
and the GradientHeader:
const GradientHeader = props => (
<View style={{ backgroundColor: '#eee' }}>
<LinearGradient
colors={['red', 'blue']}
style={[StyleSheet.absoluteFill, { height: Header.HEIGHT }]}
>
<Header {...props} />
</LinearGradient>
</View>
)
Similar to this issue: React Navigation; use image in header?
For a Linear Gradient you would simply do >
//imports
import { Image, StyleSheet, View } from 'react-native';
import { Header } from 'react-navigation' ;
import LinearGradient from 'react-native-linear-gradient';
//header
Create the Header component which is wrapped in the Linear Gradient.
by making the header backgroundColor: 'transparent' you will then show the Linear Gradient wrapping it.
const GradientHeader = props => (
<View style={{ backgroundColor: '#eee' }}>
<LinearGradient
colors={['#00a8c3', '#00373f']}
style={[StyleSheet.absoluteFill, styles.linearGradient]}
/>
<Header {...props} style={{ backgroundColor: 'transparent' }}/>
</View>
);
Return the screen with the header being your GradientHeader component.
const SimpleStack = StackNavigator({
Home: {
screen: MyHomeScreen,
},
}, {
navigationOptions: {
headerTitleStyle: { color: '#fff' },
header: (props) => <GradientHeader {...props} />,
}
});
Should look something like this with the above code.
Gradient Header
You can use LinearGradient component from the expo. It is a useful component and you can't install another library like react-native-linear-gradient. https://docs.expo.io/versions/latest/sdk/linear-gradient/. By the way, you can change the back button. It is easy.
You can implement it on inside screen with navigationOptions like that
static navigationOptions = ({ navigation }: any) => {
const onGoBack = () => navigation.goBack();
return {
header: (props: any) => <GradientHeader {...props} />,
headerStyle: { height: 68, backgroundColor: "transparent", color: colors.white },
headerTitle: "Sign Up",
headerTitleStyle: { color: colors.white, fontSize: 18 },
headerLeft: (
<TouchableOpacity style={{ width: 32, height: 32, paddingLeft: 8 }} onPress={onGoBack}>
<Image source={images.back} resizeMode="center" style={{ width: 32, height: 32 }} />
</TouchableOpacity>
),
};
};

Categories