通过点击overlay关闭react native模式

Close react native modal by clicking on overlay?

本文关键字:react native 模式 关闭 overlay      更新时间:2023-09-26

transparent选项为true时,是否可以通过点击覆盖来关闭react native模态?文档没有提供任何相关信息。这可能吗?

如果我理解正确的话,你想在用户点击模态之外的时候关闭模态,对吗?

如果是,我在一段时间前搜索了这个,我记得的唯一解决方案是这个(这是一个我一直在使用):

render() { 
  if (!this.state.modalVisible)
    return null
  return (
     <View>
        <Modal 
          animationType="fade"
          transparent={true}
          visible={this.state.modalVisible}
          onRequestClose={() => {this.setModalVisible(false)}}
        >
          <TouchableOpacity 
            style={styles.container} 
            activeOpacity={1} 
            onPressOut={() => {this.setModalVisible(false)}}
          >
            <ScrollView 
              directionalLockEnabled={true} 
              contentContainerStyle={styles.scrollModal}
            >
              <TouchableWithoutFeedback>
                <View style={styles.modalContainer}>
                  // Here you put the content of your modal.
                </View>
              </TouchableWithoutFeedback>
            </ScrollView>
          </TouchableOpacity>   
        </Modal> 
     </View>
  )
} 
// Then on setModalVisible(), you do everything that you need to do when closing or opening the modal.
setModalVisible(visible) {
    this.setState({
        modalVisible: visible,
    })
}
<标题>

这基本上是在整个屏幕中使用TouchableOpacity来获取用户点击关闭模态的时间。TouchableWithoutFeedback是为了避免TouchableOpacity在模态内部工作。

如果你有更好的解决方案,请在这里分享。

另一个解决方案:

// Modal.js
import React from 'react';
import {
  TouchableWithoutFeedback,
  StyleSheet,
  Modal,
  View,
} from 'react-native';
import t from 'prop-types';

class MyModal extends React.Component {
  static propTypes = {
    children: t.node.isRequired,
    visible: t.bool.isRequired,
    dismiss: t.func.isRequired,
    transparent: t.bool,
    animationType: t.string,
  };
  static defaultProps = {
    animationType: 'none',
    transparent: true,
  };
  render() {
    const { props } = this;
    return (
      <View>
        <Modal
          visible={props.visible}
          transparent={props.transparent}
          onRequestClose={props.dismiss}
          animationType={props.animationType}
        >
          <TouchableWithoutFeedback onPress={props.dismiss}>
            <View style={styles.modalOverlay} />
          </TouchableWithoutFeedback>
          <View style={styles.modalContent}>
            {props.children}
          </View>
        </Modal>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  modalContent: {
    flex: 1,
    justifyContent: 'center',
    margin: '5%',
  },
  modalOverlay: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'rgba(0,0,0,0.5)'
  },
});

export default MyModal;

使用例子:

// SomeScreen.js
import React from 'react';
import { View, Text, Button } from 'react-native';
import Modal from './Modal';

class SomeScreen extends React.Component {
  state = {
    isModalVisible: false,
  };
  showModal = () => this.setState({ isModalVisible: true });
  hideModal = () => this.setState({ isModalVisible: false });
  render() {
    return (
      <View>
        <Button onPress={this.showModal} />
        <Modal
          visible={this.state.isModalVisible}
          dismiss={this.hideModal}
        >
          <Text>Hello, I am modal</Text>
        </Modal>
      </View>
    );
  }
}

解决方案简单。你需要一个TouchableOpacity用于点击外部,另一个TouchableOpacity用于实际的模态,它将不做任何操作。

import { View, StyleSheet, TouchableOpacity, Modal} from 'react-native';
const Screen = () =>  {
  const [modalVisible, setModalVisible] = useState(false);
  return (
      <View>
          <Modal
              animationType="slide"
              transparent={true}
              visible={modalVisible}
              onRequestClose={() => setModalVisible(false) }
            >
              <TouchableOpacity style={styles.modalContainer} onPress={() => setModalVisible(false)} >
                  <TouchableOpacity style={styles.modal} activeOpacity={1} >
                      Modal Content...
                  </TouchableOpacity>
              </TouchableOpacity>
          </Modal>
      </View>
  )
}
const styles = StyleSheet.create({
  modalContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  modal: {
    width: 155,
    height: 300
  },
});
export default Screen;   

activeOpacity={1}只是删除touchableOpacity淡出效果

我试图实现一些建议的答案,但是没有一个工作与按钮内模态

我在谷歌周围发现,而不是使用TouchableWithoutFeedback,称为Pressable的本地组件允许你检查你点击什么,因此允许你只在点击它时关闭,而不是它的孩子。

return (
   <View>
      <Modal 
        animationType="slide"
        transparent={true}
        visible={visible}
        onRequestClose={() => {
           setVisible(false)}}
      >
        <Pressable
          onPress={(event) => event.target == event.currentTarget && setVisible(false)}
          style={styles.background}
        >
          <View style={styles.modal}>
             //Content of the modal
          </View>
        </Pressable>   
      </Modal> 
   </View>
)

在这里找到答案。

下面是我的简单实现:

<TouchableWithoutFeedback onPress={}> // Code to close your modal goes here
    <View style={styles.background}> // The view to drawn the background
            <View
                onStartShouldSetResponder={() => true}
                style={styles.container}
            > // The view to drawn your modal
            // Your content
            </View>
        </Androw>
    </View>
</TouchableWithoutFeedback>

我使用TouchableWithoutFeedback,因为我不想在点击它时改变背景颜色。我还在模态视图上添加了onStartShouldSetResponder,以防止当你在视图内单击时关闭模态。

我也没有使用Modal组件,因为我使用了react-navigation。

我们可以加上:

import { TouchableOpacity } from 'react-native';
    <TouchableOpacity onPress={()=>this.setState({modalVisibilty:false})}>
    <View style={{opacity:0, flex:1 }}/>
    </TouchableOpacity>

在窗口下面,另一个在上面,改变布局风格,以适合你的屏幕。

解释:

你将制作2个大的隐藏按钮来捕捉用户触摸并将模态可见性状态更改为false。

<Modal isVisible={this.state.isVisible}
onBackdropPress={() => this.setState({ isVisible: false })}>
<View style={{ flex: 1 }}>
<Text>I am the modal content!</Text>
</View>
</Modal>

使用TouchableWithoutFeedback和react-native的Modal最好和最简单的方法是

<Modal
  visible={visible}//modal visible true or false
  onRequestClose={()=>onClose(false)} // function to close modal
  transparent={true}
>
 <TouchableWithoutFeedback
   onPress={()=>onClose(false)}//outer button/view
   <View style={{flex:1, backgroundColor:'rgba(0,0,0,0.5)'}}>//for transparent view, this is outer view
    <TouchableWithoutFeedback>// outer button so any child view can be added
      <View>// this inner view
       <View>
       //your content goes here
       </View>
      </View>
    </TouchableWithoutFeedback>
   </View>
 </TouchableWithoutFeedback>
</Modal>

如果你想添加平面列表,最好提供高度,这样内容就不会从视图中消失

        <Modal
            animationType="slide"
            closeOnClick={true}
            transparent={true}
            visible={this.state.modalVisible}
            >
            <TouchableOpacity onPress={() => { this.setModalVisible(!this.state.modalVisible)}} style={{flex:1, justifyContent:'center', alignItems:'center',}}>
                <View style={{flex:0.2,backgroundColor:'white', margin:20, borderRadius:20, borderWidth:2, borderColor:'gray'}}>
                    <Text style={{margin:20}}>모달 테스트</Text>
                </View>
            </TouchableOpacity>
        </Modal>

这个代码是我的解决方案。

如果您正在使用expo,则使用简单的代码。
这是一个完整的组件,你只需要复制粘贴就可以让它工作了。

//MyModal.js
import React from 'react';
import { BlurView } from 'expo-blur';
import { View, StyleSheet, Modal, TouchableWithoutFeedback } from 'react-native';
export const MyModal = ({ children, visible, onRequestClose, onPressOverlay, }) => {
  return (
     <Modal
      visible={visible}
      transparent
      animationType='none'
      onRequestClose={onRequestClose}
     >
       <TouchableWithoutFeedback onPress={onPressOverlay}>
         <BlurView
           style={{ ...StyleSheet.absoluteFill }}
           tint='dark'
           intensity={100}
         />
       </TouchableWithoutFeedback>
       <View style={styles.container}>
         {children}
       </View>
    </Modal>
  );
};
const styles = StyleSheet.create({
  container: {
    height: '100%',
    width: '100%',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

现在你可以把它导入到你的工作区,像这样使用它。
我使用功能组件useState钩子来显示或隐藏模态

//yourScreen.js
import React, { useState } from 'react';
import { View, Button } from 'react-native';
import { MyModal } form './path/to/MyModal.js';
const YourScreen = () => {
  const [modalVisible, setModalVisible] = useState(false);
  return (
    <View style={{ flex:1 }}>
      <MyModal
        visible={modalVisible}
        onRequestClose={()=>{
          setModalVisible(false);
        }}
        onPressOverlay={()=>{
          setModalVisible(!modalVisible);
        }}
      >
        // your modal content goes here
      </MyModal>
      <Button
        title='Show Modal' 
        onPress={()=>{
          setModalVisible(!modalVisible);
        }}
      />
    </View>
  );
}
export default YourScreen;

这是我的解决方案,

import React from "react";
import {Modal, StyleSheet, TouchableOpacity, TouchableWithoutFeedback, View} from "react-native";
// make sure the styles props is passed to the model and contains modalContainer, as well as the childrenContainer style objects.
export default class DismissibleModal extends React.Component {
    render() {
        return (
            <Modal
              animationType="slide"
              transparent={true}
              visible={this.props.visible}
              onRequestClose={() => {this.props.dismiss()}}>
              <TouchableOpacity
                style={Styles.modal}
                activeOpacity={1}
                onPressOut={() => {this.props.dismiss()}}>
                    <View style={[this.props.styles.modalContainer]}>
                        <TouchableWithoutFeedback>
                            <View style={[this.props.styles.childrenContainer]}>
                                {this.props.children}
                            </View>
                        </TouchableWithoutFeedback>
                    </View>
              </TouchableOpacity>
        </Modal>
        )
    }
}

const Styles = StyleSheet.create({
    modal: {
        flex: 1,
        backgroundColor: 'transparent',
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center'
    },
    modalView: {
        backgroundColor: "white",
        borderRadius: 10,
        padding: 20,
        paddingTop: 20,
        alignItems: "center",
        shadowColor: "#000",
        shadowOffset: {
            width: 0,
            height: 9,
        },
        shadowOpacity: 0.50,
        shadowRadius: 12.35,
        elevation: 19,
  },
});

@Gui Herzog的回答是相当好的,但使TouchableOpacity作为父组件,它处理冲突时,触及子组件。

TouchableOpacity内部有多个组件不是好的做法,否则TouchableOpacity父组件内的所有组件将可点击,解决这个问题的最佳方法是,使TouchableOpacity组件处于绝对位置,在屏幕上具有100%的宽度和高度。

这里有一些例子:Modal.js

export default function(props){
    const { width, height } = Dimensions.get('window');
    const hp = hp => (hp / 100) * height;
    const wp = wp => (wp / 100) * width;
    const size = size => Math.round((size / 100) * width);
    return (
        <KeyboardAvoidingView>
            <TouchableOpacity
                style={{ position: 'absolute', width: wp(100), height: hp(100) }}
                onPress={props.onTouchOutSide}
            />
            <ScrollView>
                {/*...child*/}
            </ScrollView>
        </KeyboardAvoidingView>
    )
}

你欢迎。

这是您最好的解决方案,只需复制粘贴。它一定会成功的。

我也面临这个问题。下面是解决办法。

import React,{useState} from 'react';
import{Button,StyleSheet,View,TouchableOpacity,Modal} from 'react-native';
const App=()=>{
   const [show, setShow] = useState(false);
    return (
      <View>
        <TouchableOpacity style={{marginTop:200}}>
          <Button title='show' onPress={()=>setShow(!show)}/>
          </TouchableOpacity>   
            <Modal transparent={true} visible={show} animationType="slide">
            <TouchableOpacity activeOpacity={1} style={{backgroundColor:'#000000aa',flex:1}} onPress={()=>setShow(!show)}/>
            
            <View style={{backgroundColor:'#FFFFFF',flex: 1}}>
                <View >
                     <Button title='close' onPress={()=>setShow(!show)}/>
               </View>  
            </View>
        </Modal>
      </View>
    )};
export default App;

你可以在这里查看另一个例子:
https://snack.expo.dev/@saurabh_chavan/model-with-border-radius

如果您正在使用存储解决方案mobxredux,你可以简单地用商店的标志来解决。

下面是父代码,

      <Modal
        animationType="fade"
        transparent={true}
        visible={uiControlStore.dialogVisible}
        onRequestClose={() => {
          uiControlStore.dialogVisible = false;
        }}
      >
        <View
          style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.6)' }}
          onTouchStart={() => {
            if (!uiControlStore.childClicked) uiControlStore.dialogVisible = false;
            uiControlStore.childClicked= false;
          }}
        >
          <YourCustomDialog />
        </View>
      </Modal>

及以下是子代码。(使用mobx)

const YourCustomDialog: React.FC = observer(() => {
  const { uiControlStore } = useStores();
  return (
    <View
      style={[styles.container, styles.border]}
      onTouchStart={() => {
        uiControlStore.childClicked= true;
      }}
    >
    ...
  )
}

我意识到我来晚了。但我只是偶然发现了这个线程,Gui Herzog的答案正是我正在寻找的。如果您不想添加任何外部依赖项,那么就应该这样做。谢谢!

然而,我想在我的组件中包含一些可选的消极/积极动作按钮,并从反应原生纸中获取它们作为材料样式。那时我才意识到,反应纸可能也有情态动词。

下面是他们的文档:https://callstack.github.io/react-native-paper/modal.html
它们也有一个用于对话的组件https://callstack.github.io/react-native-paper/dialog.html

所以我最终使用了纸质Dialog如果你要在整个应用程序中使用这个库,这是值得的。Dialog和Modal在默认情况下都会处理点击外部时的解散。


这是在发现Dialog组件已经存在之前创建的一个Dialog组件。

无论如何,我将把我实现的留在这里,因为我认为这是一个很好的模板。

组件是typescript格式的。确保已经更新了@types/react-native,否则你可能会看到一些"No overload"匹配这个调用。错误。

import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {Button, Modal, Portal} from 'react-native-paper';
interface Action {
  action: () => void;
  text: string;
}
interface Props {
  closePressed: () => void;
  negativeAction?: Action;
  positiveAction?: Action;
  title?: string;
  text: string;
  visible: boolean;
}
export const Dialog: React.FC<Props> = ({
  closePressed,
  negativeAction,
  positiveAction,
  title,
  text,
  visible,
}) => {
  return (
    <Portal>
      <Modal
        visible={visible}
        onDismiss={closePressed}
        contentContainerStyle={styles.modalContainer}>
        <View style={styles.header}>
          {title && (
            <Text style={{fontWeight: 'bold', fontSize: 18, marginBottom: 10}}>
              {title}
            </Text>
          )}
          <Text style={styles.contentText}>{text}</Text>
        </View>
        <View style={styles.buttonContainer}>
          {negativeAction && (
            <Button mode="text" onPress={negativeAction.action}>
              {negativeAction.text}
            </Button>
          )}
          {positiveAction && (
            <Button mode="text" onPress={positiveAction.action}>
              {positiveAction.text}
            </Button>
          )}
        </View>
      </Modal>
    </Portal>
  );
};
const styles = StyleSheet.create({
  modalContainer: {
    borderRadius: 5,
    backgroundColor: 'white',
    padding: 10,
    margin: 20,
  },
  header: {padding: 20},
  contentText: {color: 'grey'},
  buttonContainer: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
    paddingTop: 20,
  },
});

这是我完美的工作解决方案

模态代码:

const ListInModal = ({ showListModal, onClose, data, onSelectItem }) => {
  return (
    <Modal animationType="none" transparent={true} visible={showListModal} onRequestClose={() => onClose(false)}>
      <TouchableOpacity onPress={() => onClose(false)} style={styles.centeredView}>
        <View style={styles.modalView}>
          <ScrollView showsVerticalScrollIndicator={false}>
            {data.map((item, index) => (
              <>
                <TouchableOpacity
                  onPress={() => {
                    onSelectItem(item);
                    onClose(false);
                  }}
                  style={{ height: 43, justifyContent: 'center' }}
                >
                  <Text style={styles.itemLabel}>{item.label}</Text>
                </TouchableOpacity>
                {index <= data.length - 2 && (
                  <View
                    style={{
                      borderBottomColor: colors.white,
                      opacity: 0.2,
                      borderWidth: 1,
                      marginHorizontal: (24 / 375) * screenWidth,
                    }}
                  />
                )}
              </>
            ))}
          </ScrollView>
        </View>
      </TouchableOpacity>
    </Modal>
  );
};

样式:

const styles = StyleSheet.create({
  centeredView: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#00000099',
  },
  modalView: {
    marginHorizontal: wp('5%'),
    marginVertical: hp('10%'),
    backgroundColor: colors.popupBlack,
    borderRadius: 20,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5,
  },
  itemLabel: {
    fontSize: wp('5%'),
    color: colors.white,
    paddingHorizontal: (24 / 375) * screenWidth,
  },
});

用法:

<ListInModal
  data={projectState?.lvApplicationTypeList}
  showListModal={showListModal}
  onClose={(bool) => setshowListModal(bool)}
  onSelectItem={(item) => onPressApplicationType(item.label)}
/>

我是这样做的

<Modal
      visible={isVisible}
      onRequestClose={() => setIsVisible(false)}
      transparent={true}
      
      >
          <Pressable style={{
              flex:1,
              backgroundColor:'transparent',
            
          }}
          onPress={()=>setIsVisible(false)}
          />
          {/* Here comes your component*/}
    </Modal>

让你的组件用position:absoute,这样Pressable可以覆盖整个背景。

@idiosync/react-native-modal是一个基于钩子的模态系统。

https://www.npmjs.com/package/@idiosync react-native-modal

你可以添加一个onBackgroundPress函数到配置对象来实现你想要的:

useModal(
    {
      // all config params are optional apart from renderModal
      renderModal: () => <MyModal onClose={() => setModalIsVisible(false)} someProp={someProp} />,
      onBackgroundPress: () => setModalIsVisible(false),
      animationTypeIn: AnimationType.SLIDE_TOP,
    },
    modalIsVisible,
    [someProp] // dependencies array to trigger rerenders. Empty array is passed by default
  )

2022答案-使用React Native Hooks

通过点击叠加来关闭React Native模态,最好使用可按压按钮和TouchableOpacity

在下面的示例

  • 从react-native
  • 导入可压缩文件和其他文件
import React, { useState } from 'react';
import {
  Pressable,
  View,
  Text,
  TouchableOpacity,
  ScrollView,
  Modal,
  TextInput,
  StyleSheet,
} from 'react-native';
  • 然后设置状态
const [modalVisible, setModalVisible] = useState(false);
  • 然后编写和设计您的模态
        <Modal
          animationType="slide"
          transparent={true}
          visible={modalVisible}
          onRequestClose={() => {
            setModalVisible(!modalVisible);
          }}
        >
          <TouchableOpacity
            onPress={() => setModalVisible(false)}
            style={styles.modalContainerStyle}
          >
            <Pressable
              onPress={() => setModalVisible(true)}
              style={styles.modalContent}
            >
              <ScrollView>
                <View>
                  <Text style={styles.modalTitle}>TITLE HERE</Text>
                  <Text style={styles.modalText}>
                    OTHER SMALLER TEXT HERE
                  </Text>
                  <Text style={styles.modalFormText}>AN INPUT</Text>
                  <TextInput
                    style={styles.modalInput}
                    value={inputValue}
                    onChangeText={(inputValue) => handleInputValue(inputValue)}
                    placeholder={'example@email.com'}
                  />
                  <View style={styles.btnView}>
                    <TouchableOpacity
                      onPress={() => setModalVisible(!modalVisible)}
                      underlayColor="white"
                    >
                      <View style={styles.buttonProceed}>
                        <Text style={styles.buttonText}>NEXT</Text>
                      </View>
                    </TouchableOpacity>
                  </View>
                </View>
              </ScrollView>
            </Pressable>
          </TouchableOpacity>
        </Modal>
  • 现在打开你的模式(使用文本按钮)
<Pressable onPress={() => setModalVisible(!modalVisible)}>
  <Text style={styles.openModal}>Open Modal</Text>
</Pressable>
  • 最终样式你的模式
modalContainerStyle: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'flex-end',
    backgroundColor: 'rgba(0, 0, 0, 0.3)',
  },
  modalContent: {
    borderTopLeftRadius: 27,
    borderTopRightRadius: 27,
    width: '100%',
    height: '60%',
    backgroundColor: '#FFFFFF',
    paddingLeft: 33,
    paddingRight: 33,
    overflow: 'hidden',
  },
  modalTitle: {
    marginTop: 43,
    marginBottom: 14,
    fontSize: 19,
    lineHeight: 21,
    color: 'black',
    fontFamily: 'GraphikBold',
  },
  modalText: {
    fontSize: 15,
    lineHeight: 25,
    marginBottom: 38,
    color: 'black',
    fontFamily: 'GraphikRegular',
  },
  modalFormText: {
    marginBottom: 10,
    fontSize: 15,
    color: 'black',
    fontFamily: 'GraphikMedium',
  },
  modalInput: {
    marginBottom: 99,
    height: 44,
    paddingLeft: 17,
    paddingRight: 17,
    fontSize: 16,
    borderRadius: 10,
    marginBottom: 20,
    borderWidth: 1,
    fontFamily: 'GraphikRegular',
    borderColor: 'rgba(118, 118, 118, 0.17)',
  },
  openModal: {
    marginRight: 5,
    textAlign: 'right',
    color: '#ED2125',
    fontFamily: 'GraphikMedium',
  },

最近遇到了这个问题,尝试使用两个可触摸的不透明度来解决它,你也可以通过将isdisposable值设为false来关闭on tap anywhere行为。

import { View, Text, Modal, StyleSheet, TouchableOpacity } from 'react-native';
import React from 'react';
type PropType = {
  open: boolean;
  onClose: () => void;
  isDismissable?: boolean;
  children: JSX.Element | JSX.Element[];
};
const styles = StyleSheet.create({
  modalRootContainer: {
    flexGrow: 1,
  },
  outerContainer: {
    height: '100%',
  },
});
const BottomModal = ({
  open,
  onClose,
  isDismissable = true,
  children,
}: PropType) => {
  return (
    <Modal
      visible={open}
      transparent
      onRequestClose={onClose}
      animationType='slide'
    >
      <TouchableOpacity
        style={styles.outerContainer}
        activeOpacity={1}
        onPress={() => {
          if (isDismissable) onClose();
        }}
      >
        <View style={styles.modalRootContainer}>
          <TouchableOpacity activeOpacity={1}>{children}</TouchableOpacity>
        </View>
      </TouchableOpacity>
    </Modal>
  );
};
export default BottomModal;

*这是一个非常简单和有效的解决方案,我只是把它应用到我的应用程序和它的作品,因为我想要的。只需将子组件封装到TouchableOpacity

的例子:

 <Modal
        animationType="slide"
        transparent={true}
        visible={IsCamaraShow}
        onRequestClose={() => {
          setIsCamaraShow(!IsCamaraShow);
        }}>
        <View style={Styles.centeredView1}>
        <TouchableOpacity style={Styles.centeredView1} 
        onPress={()=> setIsCamaraShow(!IsCamaraShow)}
        activeOpacity={1}
        >
          <View style={Styles.modalView1}>
           
            {cosnole.log( 'rest of your code') }
  
          </View>
        </TouchableOpacity>
        </View>
      </Modal>

我推荐以下对我很有效的方法:

  • 在模态
  • 中使用两个<Pressable>组件
  • 第一个不透明度-1和flex-1,没有内容和onPress关闭模式
  • 第二个样式根据你想要的模态内容和文本内容显示

<Modal 
  animationType="slide" 
  transparent 
  visible={isModalVisible} 
  onRequestClose={() => setIsModalVisible(false)
>
  <Pressable 
    onPress={() => setIsModalVisible(false)}
    style={{flex: 1, opacity: 0}}
  />
  <Pressable
    style{{height: '25%', width: '100%', position: 'absolute', bottom: 0, justify-content: 'center', align-items: 'center'}}
  >
    <Text>Content of modal</Text>
  </Pressable>
</Modal>

你可以安装react-native-modal它更简单它有一个onBackdropPress属性就在这里

PS:它甚至有一些动画,使它看起来比正常的模式要好得多

我已经在react native 0.64中解决了这个问题,给出了下面的代码

 <Modal  
     isVisible={ModalVisible}  
      onBackdropPress={()=>{setModalVisible(false)}}
       >
      .
      .
      . 
  </Modal>

嗨,我使用的是一个轻量级的弹出框react-native-easypopup,当你点击弹出框时它也会关闭自己。

npm i react-native-easypopup