'React native - Drag up modal from bottom while swiping up on the screen

How would one slowly drag a modal up when swiping up on the screen, drag it up completley if swiped up fast and close when swiped down.

This is just like how Snapchat works in the video shown bellow.

I have tried react-native-swipe-modal-up-down and react-native-modalize but they both don't support showing it slowly while swiping up the screen when its fully hidden.



Solution 1:[1]

You have a couple of solutions. One of the best implementations I have seen was this

Also, I recommend you to watch this on youtube, it builds something similar. Check this

For implementing I would suggest using one of these because they use react-native-gesture-handler and reanimated, and those run in UI thread, which is a lot faster and does not block the javascript thread.

Hope it helps, if you have any questions please ask.

EDITED

ANSWER

Here I am writing a sample code. This can be implemented easily with a scroll-view, I will do it with react-native-reanimated so if you want more animation you can edit and extend it. That youtube video up has another video where he implements something similar.

I won't implement full navigation, just an example but so you will know how to do it

  • I am assuming you want full-screen navigation

Create your screens (I will create one screen us it twice for example I will call it a page)

//page.js
import React from 'react';
import { Dimensions, View, StyleSheet, Text } from 'react-native';
import Constants from 'expo-constants';
interface PageProps {
  index: number;
  title: string;
}

const Page: React.FC<PageProps> = ({ index, title }) => {
  return (
    <View style={[styles.container, { backgroundColor: `rgba(0,0,50, 0.${index + 2})` }]}>
      <Text style={styles.text}>{title}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    height: Dimensions.get('screen').height - Constants.statusBarHeight, // this is important if you want full screen navigation
    alignItems: 'center',
    justifyContent: 'center',
  },
  text: {
    fontSize: 60,
    color: 'white',
    textTransform: 'uppercase',
    fontWeight: '700',
  },
});

export { Page };


// Than on another place use an animated scroll

import { StyleSheet } from 'react-native';
import Animated from 'react-native-reanimated';
import { Page } from './map/Page';

const TestScreen = (): JSX.Element => {
  return (
    <Animated.ScrollView pagingEnabled style={styles.container}>
{/* so here are your screens, for example first camera second images */}
      <Page title={'PAGE 1 '} index={0} />
      <Page title={'PAGE 2'} index={1} />
    </Animated.ScrollView>
  );
};

export default TestScreen;
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
});

Here is a small gif showing the implementation.

enter image description here

I used animated scroll-view but you can use just normal scroll view. This is with expo but is the same in react native too. I have implemented with reanimated because it is more performant when you will start to implement scroll-view inside the page(screen) because then you will have to check and handle which scroll-view is active.

If you have any questions please ask.

Solution 2:[2]

You can use react-native-bottom-sheet for that https://github.com/gorhom/react-native-bottom-sheet

you can install it using yarn add @gorhom/bottom-sheet@^4

check out the docs: https://gorhom.github.io/react-native-bottom-sheet/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Arnav Singh