leecade / react-native-swiper

The best Swiper component for React Native.
MIT License
10.4k stars 2.34k forks source link

Content of Swiper is not shown until ModalBox is fully animated #870

Open pospetur opened 5 years ago

pospetur commented 5 years ago

Which OS ?

iOS and Android

Version

Which versions are you using:

Expected behaviour

When using a react-native-modalbox to display a Swiper I expect to see the content of the Swiper while the ModalBox is being animated from the bottom of the screen. The ModalBox displays basic RN components such as Text, while animating, so I assume this has to do with the Swiper. I have tried loadMinimal and loadMinimalSize but that does not work.

Actual behaviour

The content of the Swiper will not be shown untill the ModalBox is fully animated in its final position.

How to reproduce it

To help us, please fork this component, modify one example in examples folder to reproduce your issue and include link here.

Will reproduce if this is not a known issue.

Steps to reproduce

1. 2. 3.

steve-else commented 5 years ago

I'm noticing this as well. Using 'modal' mode in React Navigation, navigating to the page with the Swiper, the contents do not appear until you start to swipe on the swiper itself. It remains blank if you don't do anything. If you change it to a normal page transition, it appears as normal.

syntax-e commented 5 years ago

I'm getting this in iOS using React Native Router Flux for navigation; Android is working as expected. This issue began immediately after upgrading React Native Router Flux from 4.0.0 to 4.0.6. React Native Router Flux depends on React Navigation which went from version 1.0.0 to 2.18.3 during this upgrade.

When presented within a modal, the swiper's content is invisible. The content becomes visible the moment the user interacts with the swiper at all.

  React Native Environment Info:
    System:
      OS: macOS 10.14.2
      CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
      Memory: 12.54 GB / 32.00 GB
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.9.0 - /usr/local/bin/node
      Yarn: 1.9.4 - /usr/local/bin/yarn
      npm: 6.6.0 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
      Android SDK:
        API Levels: 23, 24, 25, 26, 27, 28
        Build Tools: 23.0.1, 23.0.2, 23.0.3, 24.0.3, 25.0.0, 25.0.1, 25.0.2, 25.0.3, 26.0.0, 26.0.1, 26.0.2, 26.0.3, 27.0.3, 28.0.3
        System Images: android-23 | Google APIs ARM EABI v7a, android-23 | Google APIs Intel x86 Atom, android-25 | Google APIs Intel x86 Atom, android-25 | Google APIs Intel x86 Atom_64
    IDEs:
      Android Studio: 3.3 AI-182.5107.16.33.5199772
      Xcode: 10.1/10B61 - /usr/bin/xcodebuild
    npmPackages:
      react: ^16.6.3 => 16.7.0
      react-native: ^0.57.8 => 0.57.8
    npmGlobalPackages:
      react-native-cli: 2.0.1
      react-native-rename: 2.3.2
kkgelu commented 5 years ago

I'm noticing this as well. Using 'modal' mode in React Navigation, navigating to the page with the Swiper, the contents do not appear until you start to swipe on the swiper itself. It remains blank if you don't do anything. If you change it to a normal page transition, it appears as normal.

This is rather to prove it's timing issue, the following hack will make the swiper appear:

constructor(props) {
    super(props);
    this.state = { mounted: false };
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({ mounted: true });
    }, 100);
  }

  render() {
    if (!this.state.mounted) {
      return null;
    }
    return (
      <Swiper style={styles.wrapper} showsButtons={true} loop={false}>
        <View style={styles.slide1}>
          <Text style={styles.text}>Hello Swiper</Text>
        </View>
        <View style={styles.slide2}>
          <Text style={styles.text}>Beautiful</Text>
        </View>
        <View style={styles.slide3}>
          <Text style={styles.text}>And simple</Text>
        </View>
      </Swiper>
    );
  }
vikeen commented 5 years ago

I created a solution similar to @kkgelu, but for React functional components using hooks

// component init

// NOTE: Render timing hack to get swiper to render and scroll to correct slide index
    // URL: https://github.com/leecade/react-native-swiper/issues/870
    useEffect(() => {
        setTimeout(() => {
            setSwiperLoaded(true);
            setTimeout(() => {
                setGoal(GoalConfig.getById(user.goal));
            }, 100);
        }, 100);
    }, []);
// render()
{
    swiperLoaded &&
    <GoalSwiper
        // ....
        goal={goal} // scroll to the correct goal (i.e. content slide), but only after we call `setGoal`
    />
}

Without both 100ms setTimeouts the swiper will bug out and either show blank slides or miscalculate how to scroll to the

andreialecu commented 4 years ago

Ran into the same issue with the swiper in a modal on iOS. The following seems to fix it without using any arbitrary timeouts:

// Workaround for bug with swiper in modal
const [interactionsComplete, setInteractionsComplete] = useState(false);
InteractionManager.runAfterInteractions(() => setInteractionsComplete(true));
if (!interactionsComplete) return <LoadingIndicator />;
return <Swiper .../>;