React Native view is not receiving touch input inside an absolute positioned parent container?

Viewed 721

I am very familiar with zIndex and how the positioning system works with regular HTML on the web. My issue may be specific to the component library I am using (https://github.com/mrlaessig/react-native-autocomplete-input) but I can not get my drop down items to respond to touches.

I have a parent container <View> that is positioned absolutely. Inside that view, I have my <Autocomplete> component (my dropdown) that opens on click. I am not able to select the dropdown elements unless they are within the height of the parent view.

I have tried adjusting the positioning and zIndex of every container with no luck. Is this a limitation of the library or am I missing something obvious here?

EDIT: I have wrapped my autocomplete in another absolute positioned view as per the #android section of the documentation, but the same issue with index. I am testing on android but need it to work cross-platform.

Parent component:

const dropDownProps = {
  data: ['Cat', 'Dog', 'Chicken'],
  currentValue: 'Cat',
  onChange: e => {
    console.log(e, 'callback');
  },
  viewStyles: {
    flex: 1,
    marginHorizontal: 5,
  },
};

<View style={styles.container}>
  <View style={styles.bottomBar}>
    <DropDownSelect {...dropDownProps} />
  </View>
</View>

const styles = {
  container: {
    position: 'absolute',
    top: 10,
    left: 10,
    right: 10,
    borderRadius: 2,
    backgroundColor: black,
    paddingRight: 5,
    zIndex: X <-- this does nothing
  },
  bottomBar: {
    width: '100%',
    paddingBottom: 5,
    flexDirection: 'row',
    borderRadius: 20,
    alignItems: 'center',
    zIndex: X <-- this also does nothing
  },
}

My child dropdown component:

import React, {useState} from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
import Autocomplete from 'react-native-autocomplete-input';
import Icon from 'react-native-vector-icons/MaterialIcons';

const DropDownSelect = ({
  data,
  currentValue,
  onChange,
  viewStyles,
  containerStyles,
}) => {
  const [hideResults, setHideResults] = useState(true);
  const [value, setValue] = useState(currentValue);
  const onSelect = val => {
    setHideResults(true);
    setValue(val);
    onChange(val);
  };

  return (
    <View style={{minHeight: 35, ...viewStyles}}>
      <View style={{...styles.autocompleteContainer, ...containerStyles}}>
        <Autocomplete
          data={data}
          listStyle={styles.listStyles}
          inputContainerStyle={styles.inputContainer}
          keyExtractor={item => item}
          returnKeyType={'next'}
          hideResults={hideResults}
          renderTextInput={() => (
            <TouchableOpacity
              activeOpacity={0.5}
              style={styles.textInputItem}
              onPress={() => setHideResults(!hideResults)}>
              <Text style={styles.textInputItemText}>{value}</Text>
              <View style={styles.dropdownIcon}>
                <Icon
                  size={24}
                  color={'white'}
                  name="arrow-drop-down"
                />
              </View>
            </TouchableOpacity>
          )}
          renderItem={({item}) => (
            <TouchableOpacity onPress={() => onSelect(item)}>
              <Text style={styles.listTextStyle}>{item}</Text>
            </TouchableOpacity>
          )}
        />
      </View>
    </View>
  );
};

const styles = {
  autocompleteContainer: {
    flex: 1,
    left: 0,
    position: 'absolute',
    borderRadius: 2,
    right: 0,
    top: 0,
  },
  inputContainer: {
    backgroundColor: 'red',
    borderWidth: 0,
  },
  listStyles: {
    backgroundColor: 'blue',
    borderWidth: 0,
    margin: 0,
  },
  listTextStyle: {
    color: 'white',
    width: '100%',
    paddingVertical: 8,
    paddingLeft: 20,
  },
  textInputItem: {
    height: 35,
    alignItems: 'center',
    paddingLeft: 20,
    flexDirection: 'row',
  },
  textInputItemText: {
    color: 'white',
  },
  dropdownIcon: {
    marginLeft: 'auto',
    borderBottomRightRadius: 2,
    borderTopRightRadius: 2,
    height: '100%',
    width: 35,
    backgroundColor: 'red',
    alignItems: 'center',
    justifyContent: 'center',
  },
};
export default DropDownSelect;
1 Answers

I guess you would have solved your issue already, but for those who are still looking for a solution, use TouchableOpacity or any other Touchables from react-native-gesture-handler library.

It doen't matter if they are inside the parent view. You can touch them regardless.

Related