Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide component when clicking outside

Tags:

react-native

I want to hide a component when clicked outside it. Something like dismissing keyboard. I have done this by wrapping my whole view inside ToucheableWithoutFeedback by changing state onPress but Toucheables disables ScrollView.

Can you give me an idea of a way that scrollview still works?

or

How can I handle taps in views or outside my component??

my current code is something like this:

<TouchableWithoutFeedback onPress={() =>{this.setState({toggle:false})}}>
  <View>
    {//content}
  </View>

  <ScrollView>
    {//lists here}
  </ScrollView>
  {{
  if(this.state.toggle){
   return 
     (<View>
      {//The view that im hiding when clicking outside it}
     </View>)
  }
  else
   return <View/>
</TouchableWithoutFeedback>
like image 885
Damathryx Avatar asked Jul 21 '16 08:07

Damathryx


3 Answers

Kind of an old question already but it's the first result, so here it goes:

We'll fill the background of our relevant container with an invisible element that takes up the whole screen, like so:

<TouchableWithoutFeedback onPress={onBlur}>
    <View style={{width, height, position: 'absolute', left: 0, top: 0}} />
</TouchableWithoutFeedback>

This is my full modal that accepts children (styled to center them):

import {Dimensions, View, TouchableWithoutFeedback} from 'react-native';

const ModalFloating = ({children, onBlur = ()=>{} }) => {
    const [{width, height}, setSize] = useState({width: 0, height: 0});

    return (
        <View style={[styles.wrapper, {width, height}]} onLayout={() => setSize(Dimensions.get('window'))}>
            <TouchableWithoutFeedback onPress={onBlur}>
                <View style={{width, height, position: 'absolute', left: 0, top: 0}} />
            </TouchableWithoutFeedback>
        {children}
    </View>
    )
};`
like image 129
gal zakay Avatar answered Oct 06 '22 05:10

gal zakay


One approach is to have "fake" container for TouchableWithoutFeedback whis is just a layer below the actual content. Here's an example: https://rnplay.org/apps/k2RSNw

render() {
  return (
    <View style={styles.container}>
      <TouchableWithoutFeedback onPress={(evt) => this.toggleState(evt)}>
        <View style={styles.touchable}></View>
      </TouchableWithoutFeedback>
      <View style={[styles.modal, this.isModalVisible()]}>
        <Text>Modal</Text>
      </View>
    </View>
  );
}

If you want to do something specific depending on the clicked element, you can populate event data from evt that is provided to toggleState().

I've made the toggling of visibility via styles. This is because that in many cases I've dealt with there has been some kind of visual effect for toggling the element.

like image 42
Samuli Hakoniemi Avatar answered Oct 06 '22 04:10

Samuli Hakoniemi


The easy way is with a modal transparent

<Modal
          transparent
          visible={this.state.isAndroidShareOpen}
          animationType="fade"
          onRequestClose={() => {}}
        >
          <TouchableOpacity
            activeOpacity={1}
            onPress={() => {
              this.setState({
                isAndroidShareOpen: false,
              });
            }}
            style={{
              backgroundColor: 'transparent',
              flex: 1,
            }}
          >
            <TouchableOpacity
              activeOpacity={1}
              style={{
                backgroundColor: '#f2f2f2',
                left: 0,
                top: 50,
                aspectRatio: 1.5,
                width,
                position: 'absolute',
              }}
            >
                <Text>content</Text>
            </TouchableOpacity>
          </TouchableOpacity>
        </Modal>
like image 28
cristian camilo cedeño gallego Avatar answered Oct 06 '22 06:10

cristian camilo cedeño gallego