So I am able to currently dismiss the modal when clicking outside of the box, but the issue is that when I click inside the box it still dismisses. I have tried adding pointerEvents="none"
, which does not seem to work.
Here is my code:
<View>
<Modal
animationType="slide"
transparent={true}
style={{width: '100%', alignSelf: 'center', height: '100%', justifyContent: 'flex-start', backgroundColor:'green'}}
visible={this.state.modalVisible}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<TouchableWithoutFeedback onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<View style={{ backgroundColor: 'red', flex: 1}} >
<View pointerEvents="none" style={{alignSelf: 'center', width: '80%', height: '50%', backgroundColor: 'purple', top: 100}}>
<Text pointerEvents="none" >Hello World!</Text>
</View>
</View>
</TouchableWithoutFeedback>
</Modal>
</View>
So I am able to currently dismiss the modal when clicking outside of the box, but the issue is that when I click inside the box it still dismisses. I have tried adding pointerEvents="none"
, which does not seem to work.
Here is my code:
<View>
<Modal
animationType="slide"
transparent={true}
style={{width: '100%', alignSelf: 'center', height: '100%', justifyContent: 'flex-start', backgroundColor:'green'}}
visible={this.state.modalVisible}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<TouchableWithoutFeedback onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<View style={{ backgroundColor: 'red', flex: 1}} >
<View pointerEvents="none" style={{alignSelf: 'center', width: '80%', height: '50%', backgroundColor: 'purple', top: 100}}>
<Text pointerEvents="none" >Hello World!</Text>
</View>
</View>
</TouchableWithoutFeedback>
</Modal>
</View>
Share
Improve this question
edited Mar 28, 2019 at 15:59
David Schumann
14.8k13 gold badges83 silver badges105 bronze badges
asked Apr 11, 2018 at 19:04
Christian LessardChristian Lessard
4251 gold badge7 silver badges15 bronze badges
6
-
This is because you're setting this
onPress={() => { this.setModalVisible(!this.state.modalVisible); }}
yourself – Pritish Vaidya Commented Apr 11, 2018 at 19:11 - what is the workaround then? – Christian Lessard Commented Apr 11, 2018 at 19:14
-
onPress={() => {}}
, or set it in some cross button of the modal, not on the wrapper – Pritish Vaidya Commented Apr 11, 2018 at 19:15 -
Try adding
pointerEvents="box-only"
to theTouchableWithoutFeedback
– Matt Aft Commented Apr 11, 2018 at 19:18 - My goal is for the wrapper to be dismissible, but the contents (the box with the text) should not be dismissible. – Christian Lessard Commented Apr 11, 2018 at 19:18
5 Answers
Reset to default 9/**
* Sample React Native App
* https://github./facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableOpacity,
Modal,
TouchableWithoutFeedback
} from 'react-native';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props)
this.state = { modalVisible: true }
}
setModalVisible(modalVisible) {
this.setState({ modalVisible })
}
render() {
return (
<View>
<Modal
animationType="slide"
transparent={true}
style={{ width: '100%', alignSelf: 'center', height: '100%', justifyContent: 'flex-start', backgroundColor: 'green' }}
visible={this.state.modalVisible}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<TouchableWithoutFeedback onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<View style={{ backgroundColor: 'red', flex: 1 }} >
<TouchableWithoutFeedback onPress={() => { }}>
<View style={{ alignSelf: 'center', width: '80%', height: '50%', backgroundColor: 'purple', top: 100 }}>
<Text>Hello World!</Text>
</View>
</TouchableWithoutFeedback>
</View>
</TouchableWithoutFeedback>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
wele: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});a
So I got it to work, which will only work with the react-native-modal. The modal that ships with react does not work for this use case.
Modal
ponent provided by React Native doesn't provide many options to control it's behavior. I suggest you try react-native-munity/react-native-modal instead.
This way solved for me by using react-native-munity/react-native-modal and state to manage the visibility.
And properties onBackdropPress
will be work. For elements to trigger the modal, you should set the state to true. See the code below
constructor(props){
super(props);
this.state = {
isVisible:false
}
<Modal
isVisible = {this.state.isVisible}
onBackdropPress = { () => this.setState({isVisible:false})}
backdropOpacity = {0.3}
style = {styles.modal}>
</Modal>
Setting the state directly from the Onpress event worked for me. that is instead of using this:
<TouchableWithoutFeedback onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
You can change to :
<TouchableWithoutFeedback onPress={() => {
this.setState({modalVisible:false})}}>