Different tabBar icons in react navigation for selected and unselected state? - ios

I am setting up a tabbar using react navigation in react native. I am unable to setup multiple tabbar icons for selected/unselected state. Any reference or doc would help ?

tabBarIcon callback provides you the focused variable for the same.
static navigationOptions = {
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => {
const image = focused
? require('../active.png')
: require('../inactive.png')
return (
<Image
source={image}
style={styles.tabIcon}
/>
)
}
}

You can change the icon based on the activeTintColor / inactiveTintColor
static navigationOptions = {
tabBarLabel: 'Notifications',
tabBarIcon: ({ tintColor }) => (tintColor == '#e91e63' ?
<Image
source={require('./activeIcon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
:
<Image
source={require('./inactiveIcon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
tabBarOptions: {
activeTintColor: '#e91e63',
}
};
You can do something like this even if you don't use the tint color.

Related

How to make navigation inside react-native-drawer using react-native-router-flux

I have created drawer using react-native-drawer. drawer View contains ListView. Whenever click the renderRow method need to show navigation inside the drawer itself instead of top of the Welcome screen stack.
Right now: Check the Screenshot here
Expected:
want to achieve something like this - Multi Level Menu
File: Component/welcome.js
render(){
var settingPanel = <Setting closeDrawer={ () => {
this.drawer.close();
}} />
return(
<Drawer
ref={c => this.drawer = c}
type='overlay'
content={settingPanel}
...>
<Home />
</Drawer>
);
}
File: Component/setting.js
render(){
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow.bind(this)}
/>
);
}
renderRow (items) {
return(
<View>
<Text style={styles.rowText}>{items.name}</Text>
<ImageButton onPress={Actions.trans()} img={fb} />
</View>
)
};
Its navigating on top of the Welcome screen. I need to navigate on the drawer itself. How could I achieve this?
from it's documentation here
options to open drawer
Three options:
Use the open prop (controlled mode):
<Drawer
open={true}
Using the Drawer Ref:
// assuming ref is set up on the drawer as (ref) => this._drawer = ref
onPress={() => {this._drawer.open()}}
Using Context
contextTypes = {drawer: React.PropTypes.object}
// later...
this.context.drawer.open()
then to navigate to another component using react-native-router-flux you can add a TouchableOpacity component insted of <home /> then in onPress add actions.home()
and home is the key of react-native-router-flux scene component

Conditional header in react-native StackNavigator

I'm trying to control whether or not my StackNavigator header appears via this.props.navigation.state.params.
I have a screen with the following navigationOptions:
static navigationOptions = ( {navigation} ) => ({
header: navigation.state.params.headerConfig,
});
and I navigate to the screen as follows:
<Button
onPress={() => navigate('MyScreen', { headerConfig: _____} ) }
title="Continue"
/>
, where ____ is what I am unsure about. If I put null then the header disappears, but what can I put there if I don't want the header to disappear?
I tried entering HeaderProps instead of ____.
Any help or alternative approaches would be much appreciated.
If you don't want it do disappear then don't set it to null, leave it undefined and you will get the default one.
static navigationOptions = ({navigation}) => {
if (navigation.state.params.hideHeader) {
return {header: null}
}
return {title: 'Home'}
}

Mode in react native picker not working

I want to make a gender selection using picker. but the mode is not working in ios. Im not sure in android.
<Picker
style={{justifyContent: 'center',backgroundColor: 'white'}}
selectedValue={this.state.gender}
onValueChange={(gender) => this.setState({ gender })}
mode='dialog'
>
<Item label="Male" value="Male" />
<Item label="Female" value="Female" />
</Picker>
Hope anyone could give some suggestion..
Thank you
The <Picker> component renders as a UIPickerView on iOS - that's what you're seeing there. This picker is rendered in-place rather than in a modal (as is the case on Android) - the mode prop you specified only applies to Android.
There are two options: render the picker within something like a <Modal> or use a different component entirely.
I solved this type of issue by doing like this.
import PickerExample from './PickerExample.js';
class Sample extends React.Component {
constructor(props) {
super(props);
this.state = {gender: '',};
this.updateGender = this.updateGender.bind(this);
}
updateGender(val){
this.setState({
gender: val
},function(){
alert("callback function as your wish")
});
}
render(){
return (
<PickerExample gender={this.state.gender} updateGender={this.updateGender.bind(this)} />
);
}
The PickerExample.js file look like this.
export default PickerExample = (props) => {
return (
<Picker selectedValue = {props.gender} onValueChange = {props.updateGender}>
<Picker.Item label = "MALE" value ="Male" />
<Picker.Item label = "Female" value = "female" />
</Picker>
);
}
I use the .ios.jsx extension for the iOS specific picker. Which I code as follows:
export const SelectWidget = ({
selectedOption,
setSelectedOption,
placeholderLabel,
options
}) => {
const items = options.map((option) => {
return <Picker.Item
key={option.key ?? option.label}
label={option.label}
value={option.value}
/>;
});
return (
<Picker
onValueChange={(value) => {
setSelectedOption(value);
}}
placeholder={{
label: placeholderLabel,
value: null,
}}
selectedValue={selectedOption}
style={{
width: '100%', // fill up the width of the device (without this, nothing gets displayed
}}
itemStyle={{
height: 150, // this reduces the height of the selector
color: colors.text, // if you're in dark mode set this to white.
}}
>
// default item
<Picker.Item label={placeholderLabel} value={null} />
{items}
</Picker>
);
};

ReactNative - Why does my custom NavigationBar component render at the bottom of the screen?

I want to display a navigation bar on top of the screen using React's Navigator and this custom NavigationBar component.
I am using the following code, but for some reason the navigation bar renders at the bottom of the screen:
import NavigationBar from 'react-native-navbar'
class MyDebts extends Component {
constructor(props) {
super(props)
this.state = {
selectedTab: 'persons'
}
}
_renderScene(route, navigator) {
console.log('render scene with route: ', route)
return <route.component route={route} navigator={navigator} />
}
render() {
return (
<Provider store={store}>
<TabBarIOS selectedTab={this.state.selectedTab}>
<TabBarIOS.Item
selected={this.state.selectedTab === 'persons'}
title='Persons'
onPress={() => {
this.setState({
selectedTab: 'persons',
})
}}>
<Navigator
initialRoute={{ name: 'Persons', component: PersonsRootComponent }}
renderScene={this._renderScene}
navigationBar={<NavigationBar style={styles.nav} title={{title: 'Persons'}}/>}
/>
</TabBarIOS.Item>
</TabBarIOS>
</Provider>
)
}
}
const styles = StyleSheet.create({
nav: {
height: 160,
backgroundColor: 'red'
}
})
The PersonsRootComponent renders properly, but I have no idea why the NavigationBar is placed on the bottom of the screen...
If you want to put the navbar somewhere else other than the bottom, you need absolute positioning on the navbar.
container: {
width: width,
flexDirection: 'row',
position:'absolute',
top:0,
left:0
},

How to change the title of the NavigatorIOS without changing the route in React Native

I have a NavigatorIOS and TabBarIOS in my app. I want to change the title of the current route when a tab selected.
the first way that didn't work
While creating NavigatorIOS, I user a variable at state object but updating state didn't change the title. (even though the render is called again)
onTabChanged: function (title) {
this.setState({
selectedTab: title,
});
},
render() {
return (
<NavigatorIOS
...
initialRoute={{
component: Tabs,
title: this.state.selectedTab,
passProps: {
onTabChanged: this.onTabChanged
}
}}
/>
);
},
the second way that didn't work
I also tried updating the state of the the NavigatorIOS which I referred as nav. There is a routeStack object in the state of the NavigatorIOS which keeps an array of the route items. So I updated the array via setState of the NavigatorIOS but it didn't work either.
the third way that didn't work
I tried to change the title from Objective C as Native Module but I couldn't reach to that specific navigation bar from the NSObject.
I hope someone can help.
I think you're supposed to be able to do this with navigator.replace but at the moment the replacement of the title seems to be broken:
https://github.com/facebook/react-native/issues/476
var route = this.props.navigator.navigationContext.currentRoute;
route.title = "newTitle";
route.rightButtonTitle = "newRightButtonTitle",
route.onRightButtonPress = () => {
;
};
this.props.navigator.replace(route);
BTW, you can also change tintColor of NavigatorIOS by following code...
var app = React.createClass({
getInitialState: function() {
return {
shadowHidden: false,
barTintColor: '#f04f46',
titleTextColor: '#fff',
tintColor: '#fff',
}
},
_navigator : function(navigatorProps){
this.setState(navigatorProps);
},
render: function(){
return <NavigatorIOS ref='nav' style={styles.container}
shadowHidden={this.state.shadowHidden}
barTintColor={this.state.barTintColor}
titleTextColor={this.state.titleTextColor}
tintColor={this.state.tintColor}
translucent={false}
initialRoute={{
title: title,
component: component,
passProps: Object.assign({
navigatorHook: this._navigator,
}, this.props),
}}
/>;
}
});
Now, in next Componet
this.props.navigatorHook({tintColor: 'red'});

Resources