ptomasroos / react-native-scrollable-tab-view

Tabbed navigation that you can swipe between, each tab can have its own ScrollView and maintain its own scroll position between swipes. Pleasantly animated. Customizable tab bar
https://www.npmjs.com/package/react-native-scrollable-tab-view
6.94k stars 2.29k forks source link

Tab buttons stop working properly when returning to a page #684

Closed typhoon2099 closed 6 years ago

typhoon2099 commented 7 years ago

I have react-native-navigation installed to handle navigating through the app. When I navigate back to a page with a ScrollableTabView then the buttons stop working. The tab changes it's styling to be active but the coloured bar stays still, as does the active ScrollView. Furthermore the tabs can still be swiped between but they do not snap to the closest ScrollView. I'm using a custom TabBar:

import React, { Component, PropTypes } from 'react';
import { Animated, StyleSheet, Text, View, ViewPropTypes } from 'react-native';
import TabBarButton from './TabBarButton';

const styles = StyleSheet.create({
  tab: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingBottom: 10,
  },
  flexOne: {
    flex: 1,
  },
  tabs: {
    height: 50,
    flexDirection: 'row',
    justifyContent: 'space-around',
    borderWidth: 1,
    borderTopWidth: 0,
    borderLeftWidth: 0,
    borderRightWidth: 0,
    borderColor: '#EFF0F0',
  },
});

class TabBar extends Component {
  constructor(props) {
    super(props);
    this.renderTab = this.renderTab.bind(this);
  }

  renderTab(name, page, isTabActive, onPressHandler) {
    const {
      activeTextColor,
      inactiveTextColor,
      textStyle,
    } = this.props;
    const textColor = isTabActive ? activeTextColor : inactiveTextColor;
    const fontWeight = 'bold';

    return (
      <TabBarButton
        style={styles.flexOne}
        key={name}
        accessible
        accessibilityLabel={name}
        accessibilityTraits="button"
        onPress={() => {
          return onPressHandler(page);
        }}
      >
        <View style={[styles.tab, this.props.tabStyle]}>
          <Text style={[{ color: textColor, fontWeight }, textStyle]}>
            {name}
          </Text>
        </View>
      </TabBarButton>
    );
  }

  render() {
    const containerWidth = this.props.containerWidth;
    const numberOfTabs = this.props.tabs.length;
    const tabUnderlineStyle = {
      position: 'absolute',
      width: containerWidth / numberOfTabs,
      height: 4,
      backgroundColor: '#175FA1',
      bottom: 0,
    };

    const translateX = this.props.scrollValue.interpolate({
      inputRange: [0, 1], outputRange: [0, containerWidth / numberOfTabs],
    });

    return (
      <View
        style={[styles.tabs, { backgroundColor: this.props.backgroundColor }]}
      >
        {this.props.tabs.map((name, page) => {
          const isTabActive = this.props.activeTab === page;
          const renderTab = this.props.renderTab || this.renderTab;
          return renderTab(name, page, isTabActive, this.props.goToPage);
        })}
        <Animated.View
          style={[
            tabUnderlineStyle,
            { transform: [{ translateX }] },
            this.props.underlineStyle,
          ]}
        />
      </View>
    );
  }
}

TabBar.propTypes = {
  goToPage: PropTypes.func,
  activeTab: PropTypes.number,
  tabs: PropTypes.arrayOf(PropTypes.string),
  backgroundColor: PropTypes.string,
  activeTextColor: PropTypes.string,
  inactiveTextColor: PropTypes.string,
  tabStyle: ViewPropTypes.style,
  textStyle: Text.propTypes.style,
  renderTab: PropTypes.func,
  underlineStyle: ViewPropTypes.style,
  scrollValue: PropTypes.object,
  containerWidth: PropTypes.number,
};

TabBar.defaultProps = {
  goToPage() {},
  activeTab: null,
  tabs: [],
  activeTextColor: '#175FA1',
  inactiveTextColor: '#A7A7A7',
  backgroundColor: '#FAFAFA',
  tabStyle: null,
  textStyle: {
    fontSize: 16,
  },
  underlineStyle: null,
  scrollValue: null,
  containerWidth: null,
  renderTab: null,
};

export default TabBar;

Any clues as to why this isn't working properly are greatly appreciated, currently I can't figure out how the ScrollableTabView is figuring out the current active tab while it's still working so I haven't been able to debug it when it's not working.

typhoon2099 commented 7 years ago

I forgot to mention, I'm still having the same issue when using ScrollableTabView.ScrollableTabBar, the buttons don't work properly when navigating back to the Screen.

Elinion commented 7 years ago

I'm having the same issue, anyone has some clues?

antoxann96 commented 7 years ago

@typhoon2099 Have you found solution for this issue?

typhoon2099 commented 7 years ago

Not yet. It's the last bug in my project, I'm working on it so I'll post if I find a solution.

antoxann96 commented 7 years ago

@typhoon2099 I`ve found solution. Just try using showModal API instead of Push screen API from react-native-navigation. Thats works for me!

typhoon2099 commented 7 years ago

Are you using the modal full screen so it looks like a page?

antoxann96 commented 7 years ago

Yes, it definitely looks like usual screen, with top nav bar, back button (if needed etc)

shuse2 commented 7 years ago

It seems like this problem is related to https://github.com/wix/react-native-navigation/issues/1317

The react-native-navigation does not handle ViewPagerAndroid correctly. In the issues they provide the way to fix temporally and you need to apply it to ScrollableTabView

lgn-lvx3 commented 7 years ago

@shuse2 Did you get this to work? Just so I understand we need to add the ViewPagerAndroid type view to the actual ScrollableTabView (like the inner component that it renders) or do we need to add it manually to the ScrollableTabView code itself, that lives in node_modules?

shuse2 commented 7 years ago

It kinda works, but I needed to add like < ScrollableTabView style={{ flex: this.state.visible ? 1 : 0 }} /> when I use.

Since i don't need the animation between tabs for now, so my solution was to just fork and not use ViewPagerAndroid.

shuse2 commented 7 years ago

I just realized that latest version is not pushed to npm, and on the latest version it doesn't use ViewPagerAndroid. so, if you use the master repo directly, then it works good!!

depyronick commented 7 years ago

try https://www.npmjs.com/package/react-native-scrollable-tab-view-master

kubilaytural commented 6 years ago

Thank u shuse2. I worked for me.