react-nativetouchableopacitytouchablewithoutfeedback

TouchableOpacity outside parent View in absolute positive not works react native


I was making Picker component but what I found is Touchable Opacity in absolute positions outside from it's parent view not works.

const App = () => {
  const data = [2, 3, 4, 23]
  const [isOpen, setIsOpen] = useState(true);
  return (
    <View style={{ flex: 1, backgroundColor: 'white', justifyContent: 'center', alignItems: 'center' }}>
      <TouchableOpacity style={styles.container} onPress={setIsOpen.bind(null, true)} disabled={isOpen}>
        <Text>3</Text>
        <Image source={require('./assets/downArrow2.png')} />
        {
          isOpen && (
            <View style={styles.optionsContainer}>
              {
                data.map((number, index) => (
                  <View key={index}> 
                    <TouchableOpacity onPress={() => { setIsOpen(false) }}>
                      <View style={{ padding: 10, paddingRight: 40 }}>
  
                        <Text>{number}</Text>
                      </View>
                    </TouchableOpacity>
                    <View style={{ height: 1, width: '100%', backgroundColor: 'white' }} />
                  </View>
                ))
              }
            </View>
          )
        }
      </TouchableOpacity>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    width: 48,
    paddingVertical: 8,
    paddingRight: 5,
    paddingLeft: 8,
    borderWidth: 1,
    borderColor: 'grey',
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    position: 'relative'
  },
  optionsContainer: 
    position: 'absolute',
    top: -1,
    left: -1,
    backgroundColor: 'grey'
  }
})

So, There is outer TouchableOpacity Component & inside we are mapping many TouchableOpacity Component where children are in Absolute View.

TouchableOpacity inside it's parent's view works, but not Works outside Parent View with absolute position. Is their someOne to help me out with it???

It even Not works with TouchableNativeFeedback


Solution

  • Using TouchableOpacity from react-native-gesture-handler solves the issue of absolute position touches. However, it leads to some styling issues such as the overflow "visible" property not working.

    So what you can do is that, for the parent TouchableOpacity you can use react-native's TouchableOpacity and for children you can use react-native-gesture-handler's TouchableOpacity to get the touch to work even when positioned absolutely.

    This is the updates code. Please note the imports.

    import { useState } from 'react';
    import {View, StyleSheet, Text, TouchableOpacity as TouchableRN} from 'react-native';
    import {TouchableOpacity} from 'react-native-gesture-handler'
    
        const App = () => {
            const data = [2, 3, 4, 23]
            const [isOpen, setIsOpen] = useState(false);
            return (
              <View style={{ flex: 1, backgroundColor: 'white', justifyContent: 'center', alignItems: 'center' }}>
                <TouchableRN style={styles.container} onPress={setIsOpen.bind(null, true)} disabled={isOpen}>
                  <Text>3</Text>
                  <Image source={require('./assets/downArrow2.png')} />
                  {
                    isOpen && (
                      <View style={styles.optionsContainer}>
                        {
                          data.map((number, index) => (
                            <View key={index}> 
                              <TouchableOpacity onPress={() => { setIsOpen(false) }}>
                                <View style={{ padding: 10, paddingRight: 40 }}>
            
                                  <Text>{number}</Text>
                                </View>
                              </TouchableOpacity>
                              <View style={{ height: 1, width: '100%', backgroundColor: 'white' }} />
                            </View>
                          ))
                        }
                      </View>
                    )
                  }
                </TouchableRN>
              </View>
            )
          }
          
          const styles = StyleSheet.create({
            container: {
              width: 48,
              paddingVertical: 8,
              paddingRight: 5,
              paddingLeft: 8,
              borderWidth: 1,
              borderColor: 'grey',
              flexDirection: 'row',
              justifyContent: 'space-between',
              alignItems: 'center',
              position: 'relative'
            },
            optionsContainer: {
              position: 'absolute',
              top: -1,
              left: -1,
              backgroundColor: 'grey'
            }
          })
        
          export default App;