user3346601
user3346601

Reputation: 1049

Navigator, persist footer&header between transition

The Navigator has props for a navigationBar. The docs say:

"Optionally provide a navigation bar that persists across scene transitions"

Using that, when there is a transition to a new screen, only the content will get animated while the navigation bar doesn't change, i.e. it persists.

However, using the navigationBar props I can either have a header OR a footer that persists across transitions. I would like to have both: Header and Footer should both persist across scene transitions.

I've added an example here:

RN Play Example

If you click on 'TestComponent' or 'TestComponent2' you will see the next screen transition in from the right while the navbar at the bottom is NOT part of the transition. How can I add a header that will also NOT be part of the transition?

Is that possible with the navigator?

Upvotes: 0

Views: 144

Answers (1)

Nader Dabit
Nader Dabit

Reputation: 53711

We've not found a good solution to this so we rolled our own and it has actually worked very very well in a fairly complex app. Here is the gist of what our custom navigator component looks like:

var App = React.createClass({
    render() {
    return (
        <View style={{ flex:1 }}>
            <Header />
            <AppNavigator />
            <Footer />  
      </View>
    )
  }
})

The great thing about this is that we have a lot of control over the header and footer. I've set up a basic working example of what I'm talking about here, and pasted the code below.

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Navigator,
  TouchableHighlight
} = React;

var Header = () => (
    <View style={ styles.nav }>
    <Text>PERSISTENT Header</Text>
  </View>
)

var Footer = () => (
    <View style={ styles.footer }>
    <Text>PERSISTENT Footer</Text>
  </View>
)

var AppNavigator = React.createClass({
    renderScene(route, navigator) {
    return React.createElement(route.component, { ...this.props, ...route.passProps, navigator, route } )
  },
  render() {
    return (
        <Navigator
      style={{ flex:1 }}
      initialRoute={{ id: '0', component: Home, title: 'Home' }}
      renderScene={ this.renderScene }
      />
    )
  },
})

var App = React.createClass({
    render() {
    return (
        <View style={{ flex:1 }}>
            <Header />
            <AppNavigator />
            <Footer />  
      </View>
    )
  }
})

var Home = React.createClass({

  navigate(route, someprops) {
    this.props.navigator.push({
        component: route,
      passProps: {
        someprops: someprops
      }
    })
  },

  render: function() {
    return (
      <View style={styles.container}>
            <Text>Hello from Home</Text>
            <TouchableHighlight onPress={ () => this.navigate(About, 'ABOUT MESSAGE!!!') } style={ styles.button }>
                <Text>Go to about</Text>
            </TouchableHighlight>
      </View>
    );
  }
});

var About = React.createClass({
    render() {
    return (
        <View>
            <Text>HEllo from About</Text>
            <Text>These are the props: { this.props.someprops }</Text>
      </View>
    )
  }
})

var styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  button: {
    height:50,
    backgroundColor: '#efefef',
    borderWidth:1,
    borderColor: '#ededed'
  },
  nav: {
    height: 60,
    backgroundColor: '#ededed',
    alignItems: 'center',
    justifyContent: 'center'
  },
  footer: {
    height: 60,
    backgroundColor: '#ededed',
    alignItems: 'center',
    justifyContent: 'center'
  }
});

AppRegistry.registerComponent('App', () => App);

Upvotes: 1

Related Questions