Saltar al contenido

¿Cerrar reaccionar modal nativo haciendo clic en la superposición?

Solución:

Si entendí correctamente, desea cerrar el modal cuando el usuario haga clic fuera de él, ¿verdad?

Si es así, busqué esto hace algún tiempo y la única solución que recuerdo fue esta (que es la que he estado usando hasta ahora):

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,
    })
}

Explicación

Básicamente, se usa TouchableOpacity en toda la pantalla para obtener cuando el usuario hace clic para cerrar el modal. El TouchableWithoutFeedback es para evitar que TouchableOpacity funcione dentro del Modal.

Si tiene una mejor solución, compártala aquí.

Otra solución:

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

Ejemplo de uso:

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

Solución simple. Necesita un touchOpacity para hacer clic en el exterior y otro touchOpacity para modal real que no hará nada en Press.

import React, { Component } from 'react'
import { View, StyleSheet, TouchableOpacity, Modal} from 'react-native';

export class Modal extends Component {
    constructor(props){
        this.state = { modalVisible : true}
    }
    render() {
        return (
            <View>
                <Modal
                    animationType="slide"
                    transparent={true}
                    visible={this.state.modalVisible}
                    onRequestClose={() => { this.setState({modalVisible: false})
                    }}
                  >
                    <TouchableOpacity style={styles.modalContainer} onPress={() => { this.setState({ modalVisible : false})}}>
                        <TouchableOpacity style={styles.modal} onPress={() => console.log('do nothing')} 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 Modal;

activeOpacity = {1} solo elimina el efecto de desvanecimiento de la opacidad táctil

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *