ReactNative when scrolling auto hide navigatorios

14,570

Solution 1

Thanks to @Vincent I managed to make similar, simple code to AMScrollingnavbar in react native .. (P.S: it has a glitch but I'm satisfied with overall result)

import React, { Component } from 'react';
import { Text, View, ScrollView, Animated } from 'react-native';
import NavigationBar from 'react-native-navbar';

const AnimatedNavigationBar = Animated.createAnimatedComponent(NavigationBar);

export default class BasicListView extends Component {

  state = { isNavBarHidden: false, height: new Animated.Value(64) };

  setAnimation(disable) {
    Animated.timing(this.state.height, {
      duration: 100,
      toValue: disable ? 0 : 64
    }).start()
  };

   handleScroll(event) {
      this.setAnimation((event.nativeEvent.contentOffset.y > 64));
      this.setState({ isNavBarHidden: !this.state.isNavBarHidden });
  }

  render() {
    return (
      <View style={{ flex: 1 }} >
        <AnimatedNavigationBar style={{ backgroundColor: 'red', height: this.state.height }} />
        <ScrollView scrollEventThrottle={16} onScroll={this.handleScroll.bind(this)}>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
        </ScrollView>
      </View>
    );
  }
}

Solution 2

Hiding the NavigatorIOS bar is impossible while scrolling. Base on this issue, the navigator is inside a static component which means the bar is not rerendered on state change.So if the bar has been rendered, you cannot hide it. You can only hide it before the render of a new route. If you really want to hide the navigator bar when scrolling, you can try using this library instead: react-native-navbar

How to do it with react-native-navbar:

  1. Hide the NavigatorIOS bar for your component with the scrollView
  2. Inside this component, on the scrollView, handle the scroll with a custom function that will update the component state, which will rerender the component.
  3. Base on your state, hide or show your navigation bar.
  4. On your custom navigation bar control, bind the NavigatorIOS pop, push, replace, etc. actions you would normally use.

You can follow this issue to help you with how to do it

Your component will look like this:

class CustomComponent extends Component {
  state = { isNavBarHidden: false };

  handleScroll = () => this.setState({ isNavBarHidden: true });

  render() {
    const navbarStyle = this.state.isNavBarHidden ? { height: 0 } : {};

    return (
      <View>
        <NavigationBar style={navbarStyle} />
        <ScrollView onScroll={this.handleScroll}>
          ...
        </ScrollView>
      </View>
    );
  }
}  

EDIT: Here's the complete navigation bar example with animated height. You can animate everything you want with the Animated.createAnimatedComponent function. If you want to correctly animate the title of the buttons, you will have to use it. I use 64 for the height because it is the iOS navigation bar height, but on android the height is different, you can use Platform.select() if you need to make it work for android. You can also specify a height of 5 instead of 0 to always have a part of the navigation bar visible and pressable. In this example, the navigation bar will hide or show on every scroll, you will probably have to hide it and show it base on what you want to achieve.

import React, { Component } from 'react';
import { Text, View, ScrollView, Animated } from 'react-native';
import NavigationBar from 'react-native-navbar';

const AnimatedNavigationBar = Animated.createAnimatedComponent(NavigationBar);

export default class BasicListView extends Component {
  state = { isNavBarHidden: false, height: new Animated.Value(64) };

  setAnimation = enable => {
    Animated.timing(this.state.height, {
      duration: 400,
      toValue: enable? 64 : 0
    }).start()
  };

  handleScroll = () => {
    this.setAnimation(this.state.isNavBarHidden);
    this.setState({ isNavBarHidden: !this.state.isNavBarHidden });
  };

  render() {
    return (
      <View style={{ flex: 1 }} >
        <AnimatedNavigationBar style={{ backgroundColor: 'red', height: this.state.height }} />
        <ScrollView onScroll={this.handleScroll}>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
          <View style={{ height: 200 }}><Text>Test</Text></View>
        </ScrollView>
      </View>
    );
  }
}
Share:
14,570
Bader
Author by

Bader

Updated on June 24, 2022

Comments

  • Bader
    Bader almost 2 years

    I'm trying to hide the navbar (NavigatorIOS) when scrolling down. How can I achieve that ?

    Thanks

  • Bader
    Bader about 7 years
    Impossible ? How AMScrollingNavbar is doing it
  • Vincent D'amour
    Vincent D'amour about 7 years
    They created their own navigation bar. AMScrollingNavbar is not a react-native library, it's a native iOS library. You can use it if you want and create the corresponding react class. Or you can also modify the react-native code to remove the NavigatorIOS from its static component wrapper, but I would not recommend it. Currently, the way NavigatorIOS is coded in react-native doesn't allow you to re-render it once already rendered in a route component, this is why I'm suggesting you an alternative library.
  • Bader
    Bader about 7 years
    it can be ported but it's written in swift so it's not easy task .. react-native-bar sound good but I'm looking for something look native ... It is highly appreciated if you kindly explain your example code with animation.... thanks
  • Bader
    Bader about 7 years
    your method works but it missing the scroll end event
  • Vincent D'amour
    Vincent D'amour about 7 years
    I edited my answer with a working animated navigation bar. From there, you will be able to create the animation you want and animate components that need to.
  • glocore
    glocore almost 6 years
    The glitch you mentioned can be gotten rid of by wrapping the AnimatedNavigationBar with a View with the following styling: style={{ zIndex: 1, position: 'absolute', top: 0, left: 0, right: 0 }}