Закрыть отредактировать native modal, нажав на overlay?

Можно ли закрыть отредактировать собственный модальный, нажав на overlay, когда опция transparent true? Документация ничего не сообщает об этом. Возможно ли это?

Ответ 1

Если я правильно понял, вы хотите закрыть модальный, когда пользователь нажимает на него, верно?

Если да, я искал это некоторое время назад, и единственным решением, которое я помню, был этот (тот, который Я использовал до сих пор):

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.

Если у вас есть лучшее решение, пожалуйста, поделитесь этим.

Ответ 2

Другое решение:

// 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>
    );
  }
}

Ответ 3

Мы можем решить это, добавив:

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

под окном и еще один выше и измените стиль макета, чтобы соответствовать вашему экрану.

Объяснение:

Вы сделаете 2 большие скрытые кнопки, чтобы поймать прикосновение пользователя и изменить модальное состояние видимости на false.

Ответ 4

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

Ответ 5

        <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>

этот код - мое решение

Ответ 6

Вот моя простая реализация:

<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 в модальное представление, чтобы предотвратить закрытие модального окна при щелчке внутри представления.

Я также не использую модальный компонент, потому что я сделал это, используя реагирующую навигацию.

Ответ 7

Привет, я использую облегченное всплывающее окно react-native-easypopup легкий-всплывающее окно, react-native-easypopup также закрывается при нажатии на всплывающее окно.

npm я react-native-easypopup