SteffeyDev / react-native-popover-view

A well-tested, adaptable, lightweight <Popover> component for react-native
MIT License
614 stars 92 forks source link

Multiple Popovers opening in sequence, second not opening when triggered by button in first #27

Closed huynguyen2903 closed 6 years ago

huynguyen2903 commented 6 years ago

Sorry for my bad English. I want to use react-native-popover-view as a guide for new user. If user read the first guide and they click "Ok" it will open the second guide. My code is below. Thank you for your help ! "react-native-popover-view": "version": "1.0.9", "react-native": "version": "0.57.4",

export default class App extends Component<Props> {
  componentDidMount() {
    this.setState({ isVisible: true });
  }
  state = {
    isVisible: false,
    isVisible2: false
  };

  showPopover() {
    this.setState({ isVisible: true });
  }
  showPopover2() {
    this.setState({ isVisible2: true });
    this.setState({ isVisible: false });
  }

  closePopover() {
    this.setState({ isVisible: false });
  }
  render() {
    return (
      <View style={styles.container}>
        <Popover
          isVisible={this.state.isVisible}
          fromView={this.touchable}
          onClose={() => this.closePopover()}
        >
          <Text style={styles.test}>The first guide</Text>
          <TouchableHighlight
            style={styles.button}
            onPress={() => this.showPopover2()}
          >
            <Text>go to second</Text>
          </TouchableHighlight>
        </Popover>
        <Popover
          isVisible={this.state.isVisible2}
          fromView={this.touchable2}
          onClose={() => this.closePopover()}
        >
          <Text style={styles.test}>The second guide</Text>
          <TouchableHighlight
            style={styles.button}
            onPress={() => this.showPopover()}
          >
            <Text>Press me</Text>
          </TouchableHighlight>
        </Popover>

        <TouchableHighlight
          ref={ref => (this.touchable = ref)}
          style={styles.button}
          onPress={() => this.showPopover()}
        >
          <Text>Press me</Text>
        </TouchableHighlight>
        <Text
          ref2={ref2 => (this.touchable2 = ref2)}
          tyle={styles.instructions}
        >
          text 1
        </Text>
      </View>
    );
  }
}
SteffeyDev commented 6 years ago

That code looks like it should work, what is not working? If the second popover is not showing when you click the button, you could try

showPopover2() {
  this.setState({ isVisible2: true }, () => this.setState({ isVisible: false }));
}

or

<Popover
  isVisible={this.state.isVisible}
  fromView={this.touchable}
  doneClosingCallack={() => this.setState({ isVisible2: true })}
  onClose={() => this.setState({ isVisible: false })}
  >
  <Text style={styles.test}>The first guide</Text>
  <TouchableHighlight
    style={styles.button}
    onPress={() => this.setState({ isVisible: false })}
  >
    <Text>go to second</Text>
  </TouchableHighlight>
</Popover>

Using the doneClosingCallback will make sure the second popover doesn't trigger until the first one is done closing.

huynguyen2903 commented 6 years ago

it's still not working. The second popover didn't show. it's work for you ?

huynguyen2903 commented 6 years ago

The state of isVisible2 was changed "true" but the popover 2 not showing

SteffeyDev commented 6 years ago

Ok, so after a bit of debugging I have identified two issues with the code and several solutions. Firstly,

<Text
  ref2={ref2 => (this.touchable2 = ref2)}
  tyle={styles.instructions}
>

should be

<Text
  ref={ref => (this.touchable2 = ref)}
  style={styles.instructions}
>

Once that is fixed, the next issue is that you cannot show more than one popover using Modals at one time. If you show both Popovers in Modals, you must wait until the first closes completely before showing the second. You could:

SteffeyDev commented 6 years ago

I have working code, so let me know if you can't get it working with these suggestions

SteffeyDev commented 6 years ago

I'm considering making a change to the popover code to make this easier, which would detect when there is a modal open and then delay the second popover from trying to show until the first is closed... so you are welcome to wait for that update, but no guarantee on timing.

huynguyen2903 commented 6 years ago

I can't set timeout for this because my client request that popover will be closed when user click on button. I try showInModal={false} it's work but the component is overplay the popover. How can I fix it. The picture is below. image

SteffeyDev commented 6 years ago

When I said set timeout, I meant using onPress={() => this.setState({ isVisible: false }, () => setTimeout(() => this.setState({ isVisible2: true }), 500)) as the onPress handler for the button in the first Popover. That way it triggers the first one to hide, waits 0.5 seconds (which you can adjust if the Popover needs more time to close), and then triggers the second one to show.

SteffeyDev commented 6 years ago

And showInModal={false} is actually not working currently, I haven't tested in a while, but I fixed last night and it will work in the next release. I think your best bet is with the timeout or doneClosingCallback.

huynguyen2903 commented 6 years ago

It's work. Thank you very much @SteffeyDev.