TouchableOpacity和TextInput在位于以下位置的视图内不起作用:“绝对”

问题描述

我有一个自定义下拉菜单,其中下拉视图绝对定位。当组件直接位于滚动视图内部时,我将无法执行文本输入和可触摸操作。

自定义组件代码

import React,{ Component } from 'react';
import { View,Text,StyleSheet,TouchableOpacity,ScrollView,TextInput } from 'react-native';
import Icon_Feather from 'react-native-vector-icons/Feather';
import Icon_MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import PropTypes from 'prop-types';
import _ from 'lodash';

let dropDownData = []

class MultiSelectDropdown extends Component {

    constructor(props) {
        super(props);

        this.state = {
            isVisible: false,data: [],searchData: [],selectedData: [],// selectAllStatus: false,searchableText: null,defaultSelectedValues: ''
        }
    }

    UNSAFE_componentwillReceiveProps = async (props) => {
        await this.setState({
            data: props.data,defaultSelectedValues: props.selectedData != undefined ? props.selectedData : [],isVisible: props.isVisible
        })
        // alert(this.state.data)
        await this.formatReceivedData()
    }

    formatReceivedData = async () => {
        var pushedData = []
        let tempData = JSON.parse(JSON.stringify(this.state.data))
        tempData.forEach(element => {
            let obj = element
            Object.assign(obj,{ selected: false })
            pushedData.push(obj)
        });

        await this.setState({
            selectedData: pushedData,searchData: pushedData,})

        if (this.state.defaultSelectedValues.length > 0)
            await this.checkDefaultValues();
    }

    checkDefaultValues = async () => {
        this.state.data.forEach((ele1,index1) => {
            this.state.defaultSelectedValues.forEach((ele2,index2) => {
                if (_.isEqual(ele1,ele2)) {
                    this.state.selectedData[index1].selected = true
                    this.setState({
                        selectedData: this.state.selectedData
                    })
                }
            });
        });
    }

    getLayout(layout) {
        this.setState({
            top: layout.height - 1
        });
    }

    toggle() {
        // this.setState({
        //     isVisible: ! this.state.isVisible,// },() => {
        //     const isVisible = this.state.isVisible;

        //     // if (isVisible) {
        //  //  this.props.onopen();
        //  // } else {
        //  //  this.props.onClose();
        //  // }
        // });
        this.setState({
            isVisible: !this.state.isVisible,})
    }

    selectItem = async (data,index) => {
        var tempSelectedData = this.state.selectedData

        if (tempSelectedData[index].selected == false)
            tempSelectedData[index].selected = true
        else
            tempSelectedData[index].selected = false

        var truePropertyData = tempSelectedData.filter((item) => {
            return item.selected != false
        })

        if (truePropertyData.length > this.props.maxItemsToSelect) {
            // max
            tempSelectedData[index].selected = false;
            var truePropertyData1 = tempSelectedData.filter((item) => {
                return item.selected!= false
            })
            this.removeExtraAddedProperty(truePropertyData1,index);
        } else {
            this.setState({
                selectedData: tempSelectedData,// selectAllStatus: false
            })
            this.removeExtraAddedProperty(truePropertyData,index);
        }

    }

    getSelectedItemCount = () => {
        var truePropertyData = this.state.selectedData.filter((item) => {
            return item.selected!= false
        })
        return truePropertyData;
    }

    getLabeldisplayText = () => {
        let count = this.getSelectedItemCount().length;
        return this.props.multipleDataSelectedText.replace('%d',count);
    }

    selectAll = async () => {
        var tempSelectedData = JSON.parse(JSON.stringify(this.state.selectedData))

        var status = await this.selectAllOrUnselect()

        // if (this.state.selectAllStatus) {
        if (status) {
            tempSelectedData.forEach((ele,i) => {
                tempSelectedData[i].selected= false
            });
            this.setState({
                selectedData: tempSelectedData,// selectAllStatus: false
            })

            var truePropertyData = tempSelectedData.filter((item) => {
                return item.selected!= false
            })
            this.removeExtraAddedProperty(truePropertyData,0)

        } else {
            tempSelectedData.forEach((ele,i) => {
                tempSelectedData[i].selected= true
            });
            this.setState({
                selectedData: tempSelectedData,// selectAllStatus: true
            })
            this.removeExtraAddedProperty(this.state.selectedData,0)
        }

    }

    removeExtraAddedProperty = (truePropertyData,index) => {
        let tempTruePropertyData = JSON.parse(JSON.stringify(truePropertyData))
        var actualData = []
        if (tempTruePropertyData.length > 0) {
            tempTruePropertyData.forEach(element => {
                var obj = element
                delete obj['selected']
                actualData.push(obj)
            });
        } else
            this.props.onItemChange(truePropertyData,index)

        this.props.onItemChange(actualData,index)
    }

    selectAllOrUnselect = () => {
        var returnStatus;
        var trueFilteredData = this.state.selectedData.filter((item,i) => {
            return item.selected == true
        })

        if (trueFilteredData.length == this.state.selectedData.length)
            returnStatus = true
        else
            returnStatus = false

        return returnStatus;
    }

    updateSearch = async (text) => {
        await this.setState({
            searchableText: text
        })

        let toSearch = (this.state.searchableText).toLowerCase();
        let result = this.state.data.filter(o => o[this.props.displayLabel].toLowerCase().includes(toSearch));

        await this.setState({
            searchData: result
        })
    }

    render() {
        return (
            <View style={[this.props.containerStyle,{
                ...(Platform.OS !== 'android' && {
                    zIndex: this.props.zIndex
                })
            }]}>
                <TouchableOpacity
                    onLayout={(event) => this.getLayout(event.nativeEvent.layout)}
                    onPress={() => this.toggle()}
                    activeOpacity={1}
                    style={[
                        styles.dropDown,this.props.style,this.state.isVisible && styles.noBottomradius,{
                            flexDirection: 'row',flex: 1
                        }
                    ]}
                >
                    <View style={[styles.dropDowndisplay]}>
                        {/* <Text style={[this.props.labelStyle,{ flex: 1,marginRight: 5 }]}> */}
                        {/* {this.props.placeHolder} {this.getSelectedItemCount().length} */}
                        {/* {this.getSelectedItemCount().length > 0 ?
                                'Under Test'
                            :
                                JSON.stringify(this.state.placeHolder)
                            } */}
                        {/* </Text> */}
                        {this.getSelectedItemCount().length > 0 ?
                            <Text style={[this.props.labelStyle,marginRight: 5 }]}>
                                {this.getLabeldisplayText()}
                            </Text>
                            :
                            <Text style={[this.props.labelStyle,marginRight: 5 }]}>
                                {this.props.placeHolder} {JSON.stringify(this.state.isVisible)}
                            </Text>
                        }
                    </View>

                    <View style={[styles.arrow]}>
                        {!this.state.isVisible ?
                            <Icon_Feather name="chevron-down" size={15} color={'black'} />
                            :
                            <Icon_Feather name="chevron-up" size={15} color={'black'} />
                        }
                    </View>

                </TouchableOpacity>

                <View style={[
                    styles.dropDown,styles.dropDownBox,this.props.dropDownStyle,!this.state.isVisible && styles.hidden,{
                        top: this.state.top,maxHeight: this.props.dropDownMaxHeight,zIndex: this.props.zIndex
                    }
                ]}>

                    {/* Search Text */}
                    <View style={{ width: '100%',flexDirection: 'row' }}>
                        <TextInput
                            style={[styles.input,this.props.searchableStyle]}
                            defaultValue={this.state.searchableText}
                            placeholder={this.props.searchablePlaceholder}
                            onChangeText={(text) => this.updateSearch(text)}
                        />
                    </View>

                    <ScrollView style={{ width: '100%' }} nestedScrollEnabled={true}>
                        {this.state.searchData.length > 0 ? this.state.searchData.map((item,index) => (
                            <View key={index}>
                                <TouchableOpacity
                                    style={[styles.dropDownItem,this.props.itemStyle]}
                                    onPress={() => this.selectItem(item,index)}
                                >
                                    <View style={{ flexDirection: 'row' }}>
                                        <View style={{ paddingRight: 5 }}>
                                            {(this.state.selectedData[index] != undefined && this.state.selectedData[index].selected == true) ?
                                                <Icon_MaterialIcons name={'check-Box'} size={22} color={'black'} />
                                                :
                                                <Icon_MaterialIcons name={'check-Box-outline-blank'} size={22} color={'black'} />
                                            }
                                        </View>
                                        <View style={{ justifyContent: 'center',alignItems: 'center' }}>
                                            <Text style={[this.props.labelStyle]}>
                                                {item[this.props.displayLabel]}
                                            </Text>
                                        </View>
                                    </View>
                                </TouchableOpacity>
                            </View>
                        ))
                            :
                            <Text>
                                Not Found
                            </Text>
                        }
                    </ScrollView>

                </View>
            </View >
        );
    }
}

MultiSelectDropdown.defaultProps = {
    containerStyle: {},style: {},zIndex: 5000,placeHolder: 'Select an option',labelStyle: {},dropDownStyle: {},dropDownMaxHeight: 250,itemStyle: {},displayLabel: '',searchableStyle: {},searchablePlaceholder: 'Search',multipleDataSelectedText: '%d items have been selected',data: PropTypes.array.isrequired,maxItemsToSelect: '',isVisible: false,selectAllText: 'Select All',unselectAllText: 'Un-Select All'
}

MultiSelectDropdown.propTypes = {
    containerStyle: PropTypes.object,style: PropTypes.object,zIndex: PropTypes.number,placeHolder: PropTypes.string,labelStyle: PropTypes.object,dropDownStyle: PropTypes.object,dropDownMaxHeight: PropTypes.number,itemStyle: PropTypes.object,displayLabel: PropTypes.string,searchableStyle: PropTypes.object,isVisible: PropTypes.bool,searchablePlaceholder: PropTypes.string,selectedData: PropTypes.any,multipleDataSelectedText: PropTypes.string,maxItemsToSelect: PropTypes.string,selectAllText: PropTypes.string,unselectAllText: PropTypes.string
}

const styles = StyleSheet.create({
    container: {
        flex: 1,backgroundColor: 'white',},noBottomradius: {
        borderBottomLefTradius: 0,borderBottomrighTradius: 0,dropDown: {
        paddingHorizontal: 10,paddingVertical: 5,backgroundColor: '#fff',borderTopRighTradius: 5,borderTopLefTradius: 5,borderBottomrighTradius: 5,borderBottomLefTradius: 5,borderWidth: 1,borderColor: '#dfdfdf',dropDowndisplay: {
        flexDirection: 'row',alignItems: 'center',borderTopRighTradius: 0,flexGrow: 1
    },arrow: {
        flexDirection: 'row',justifyContent: 'center',textAlign: 'center',paddingVertical: 8,borderTopLefTradius: 0,borderBottomLefTradius: 0,dropDownBox: {
        borderTopLefTradius: 0,position: 'absolute',width: '100%',zIndex: 1
    },hidden: {
        position: 'relative',display: 'none',borderWidth: 0
    },dropDownItem: {
        paddingVertical: 8,justifyContent: 'center'
    },input: {
        flex: 1,borderBottomWidth: 1,paddingHorizontal: 0,marginBottom: 2,});

export default MultiSelectDropdown;

上面的组件在视图中使用时可以正常工作,但是当将其放置在模式中时则无法工作。即我无法执行触摸和文本输入操作。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)