13

I am creating a react native app and I used a react-native modal component to open a modal and I am able to open a full modal with the following code. I have mentioned my code samples below. Now I wanted to open a half modal.

This is what I tried.

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
  ScrollView,
  TouchableOpacity,
  TextInput,
  Image,
  Modal,
} from 'react-native';

export default class Test extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      modalVisible: false,
    };
  }
  setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.header}>
          <Text style={styles.headerText}>Test Half Modal</Text>
          <TouchableOpacity
            style={styles.addButton}
            onPress={() => {
              this.setModalVisible(true);
            }}>
            <Text style={styles.addButtonText}>Open</Text>
          </TouchableOpacity>
        </View>

        <Modal
          animationType="slide"
          transparent={false}
          visible={this.state.modalVisible}
          onRequestClose={() => {
            // this.closeButtonFunction()
          }}>
          <View style={styles.footer}>
            <Text style={styles.headerText}>This is Half Modal</Text>
          </View>
          <TouchableOpacity
            style={styles.addButton}
            onPress={() => {
              this.setModalVisible(!this.state.modalVisible);
            }}>
            <Text style={styles.addButtonText}>Close</Text>
          </TouchableOpacity>
        </Modal>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#98B3B7',
    justifyContent: 'center',
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  headerText: {
    color: 'black',
    fontSize: 18,
    padding: 26,
  },
  noteHeader: {
    backgroundColor: '#42f5aa',
    alignItems: 'center',
    justifyContent: 'center',
    borderTopLeftRadius: 50,
    borderTopRightRadius: 50,
  },
  footer: {
    flex: 1,
    backgroundColor: '#ddd',
    bottom: 0,
    left: 0,
    right: 0,
    zIndex: 10,
  },
  textInput: {
    alignSelf: 'stretch',
    color: 'black',
    padding: 20,
    backgroundColor: '#ddd',
    borderTopWidth: 2,
    borderTopColor: '#ddd',
  },
  },
  addButton: {
    position: 'absolute',
    zIndex: 11,
    right: 20,
    bottom: 90,
    backgroundColor: '#98B3B7',
    width: 70,
    height: 70,
    borderRadius: 35,
    alignItems: 'center',
    justifyContent: 'center',
    elevation: 8,
  },
  addButtonText: {
    color: '#fff',
    fontSize: 18,
  },
});

Using the above code I am able to open a full modal. How can I open half modal using some styles or something else?

Sidath
  • 379
  • 1
  • 9
  • 25

4 Answers4

28

You will need a wrapper view for your Modal contents, and as you are planning to display only half the screen you will have to make it transparent. Updating the modal code like below. I put background color as blue you can change it as you want. The height is set to 50% as you wanted half and the marginTop is set to auto which will move it to the bottom half of the screen.

<Modal
  animationType="slide"
  transparent={true}
  visible={this.state.modalVisible}
  onRequestClose={() => {
    // this.closeButtonFunction()
  }}>
  <View
    style={{
      height: '50%',
      marginTop: 'auto',
      backgroundColor:'blue'
    }}>
    <View style={styles.footer}>
      <Text style={styles.headerText}>This is Half Modal</Text>
    </View>
    <TouchableOpacity
      style={styles.addButton}
      onPress={() => {
        this.setModalVisible(!this.state.modalVisible);
      }}>
      <Text style={styles.addButtonText}>Close</Text>
    </TouchableOpacity>
  </View>
</Modal>
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Guruparan Giritharan
  • 15,660
  • 4
  • 27
  • 50
  • I'm wondering if there is a way to make the background behind the modal slightly darker. – jrs Nov 16 '21 at 23:09
  • Ive put a color, you can set any color you want – Guruparan Giritharan Nov 17 '21 at 01:51
  • I don't mean the modal colour itself - I can see you've set that blue. I mean, the part above the modal. Is there a way to set an opacity so that the background appears darker and the focus is on the modal? – jrs Nov 17 '21 at 23:28
5

I was also facing the same issue ,And I came up with this The key here is to make the flex of outer View 0.5

<Modal
 isVisible={modal}
style={{ justifyContent: 'flex-end', margin: 0 }}
onBackdropPress={() => this.setState({ modal: false })}>

<View style={{ flex: 0.5, backgroundColor: 'white',justifyContent: 'space-around', alignItems: 'center' }}>
</View>

</Modal>
harshith s
  • 74
  • 4
3

You can do something like this:

 <Modal isVisible={true}
                     swipeDirection={['up', 'left', 'right', 'down']}
                     style={styles.modalView}
              > 
          <View style={styles.containerStyle}>
            <View style={styles.content}>
/**The rest of your code goes here **/
            </View>
        </View>
</Modal>

And Style it as follows

modalView: {
    margin: 0,
    justifyContent: 'flex-end'
},
containerStyle: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
     alignItems: 'flex-end'
},
content: {
    width: '95%',
    height: '50%',
    backgroundColor: 'white',
    overflow: 'hidden',
  },

Note: The key here is to use the modalView style for the modal to position and expand it from bottom to top.

RowanX
  • 1,272
  • 2
  • 14
  • 27
1
           <Modal
            animationType="slide"
            transparent={true}
            visible={true}>

            <View style={{flex:1 , backgroundColor: 'rgba(0,0,0,0.5)'}}>
                <View style={{height:50,marginTop: 'auto', backgroundColor:'#FFFFFF'}}>

                </View>
            </View>
        </Modal>