react-native touchable opacity click issue in IOS 12.02 - react-native

TouchableOpacity requires us to click two times in IOS 12.2. These issues were not in previous IOS 12.1 version.
Whenever clicking on TouchableOpacity it seems to register click but do not fire onPress event. This issue is occuring in react-native version 0.52. This issue only occurs in IOS and not in android.
Code Snippet
<FlatList
scrollEnabled={false}
data={this.props.menuData[this.props.toutIndex].Menu}
keyExtractor={(data, index) => index}
renderItem={({ item , index}) => {
//alert(categoryLinks.menu_id+""+data.menu_id);
//alert(JSON.stringify(data));
return (
<TouchableOpacity onPress={()=>this.itemDetailsPage(item)} >
<View>
<CardItem onPress={()=>this.itemDetailsPage(item)} style={[styles.menuSubCategoryCardItem, {marginLeft:0, borderLeftWidth: 6, borderLeftColor: item.itemCount ? '#00CDBE' : '#FFFFFF'}]}>
<View style={{flex:2,marginLeft:"0%"}}>
<View style={styles.menuItemImageOuterContainer}>
<View style={styles.menuItemImageInnerContainer}>
<ImageLoad
style={styles.menuItemImage}
isShowActivity={false}
borderRadius={10}
source={{ uri: item.menu_photo }}
/>
{item.ratable == 'true' ?
<View style={[styles.menuItemRatingImage,{backgroundColor:item.overall_rating==0 ? 'rgb(166,166,166)' : item.rating_color}]}>
<Text style={styles.menuItemRatingImageText}>{ item.overall_rating>0 ? parseFloat(item.overall_rating).toFixed(this.state.rating_decimal_places) : "-" }</Text>
</View>
:null}
</View>
<View style={styles.menuItemNameContainer}>
<View style={{width:'100%',}}>
<Text numberOfLines={2} style={[styles.textHeadingMenuItem,{fontSize: item.menu_name.length>50 ? 53/3.82 : 63/3.82,paddingLeft:"2%"}]}>
{this.Capitalize(item.menu_name)}
</Text>
</View>
<View style={{width:'130%',}}>
<Text numberOfLines={3} note style={[styles.textMenuItem,{paddingLeft:"2%"}]}>
{item.menu_description}
</Text>
</View>
{
item.friend_review_count > 0 ?
<View style={{flexDirection:'row',marginLeft:"2%",alignItems:'center'}}>
<Image style={styles.userIconBelowMenuItemText} source={require("../../../assets/home/blueUser.png")}>
</Image>
<Text numberOfLines={1} style={styles.MenuItemFriendsRatedText}>
{item.friend_review_count} friends have rated this.
</Text>
</View>
:
null
}
</View>
</View>
</View>
<Right>
<View style={styles.menuItemPriceOuterContainer}>
<Text style={[styles.textHeadingMenuItemPrice,{paddingTop:"5%"}]}>
{this.state.currency} {CommonFunc.numberWithCommas(
parseInt(item.menu_price)
.toFixed(categoryLinks.state.decimal_places)
)
}
</Text>
</View>
<View style={styles.menuItemPlusButtonContainer}>
{ item.itemCount == undefined || item.itemCount == 0?
<TouchableOpacity style={styles.menuItemPlusButton}
onPress={() => this.displaySelector(item.menu_price, item.Menu_Options, this.props.toutIndex, null, index, 1)}
onLongPress={() => this.displaySelector(item.menu_price, item.Menu_Options, this.props.toutIndex, null, index, 1, 1)}
rejectResponderTermination
>
<Image style={[styles.menuItemPlusButtonImage,{resizeMethod:'resize'}]} source={require("../../../assets/order/Add.png")} />
</TouchableOpacity>
:
<View style={styles.menuItemSelectorContainer}>
<Button transparent onPress={() => this.displaySelector(item.menu_price, item.Menu_Options, this.props.toutIndex, null, index, -1)} style={{paddingVertical:10, paddingLeft:2}}>
<Image source={require('../../../assets/order/decrease.png')}
style={[styles.menuItemSelectorDecreaseIcon,{resizeMethod:'resize'}]}/>
</Button>
<Button transparent>
<Text style={styles.menuItemSelectorCountText}>
{item.itemCount}
</Text>
</Button>
<Button transparent onPress={() => this.displaySelector(item.menu_price, item.Menu_Options, this.props.toutIndex, null, index, 1)}
onLongPress={() => this.displaySelector(item.menu_price, item.Menu_Options, this.props.toutIndex, null, index, 1, 1)}
style={{paddingVertical:10, paddingRight:2}}
>
<Image source={require('../../../assets/order/increase.png')}
style={[styles.menuItemSelectorDecreaseIcon,{resizeMethod:'resize'}]}/>
</Button>
</View>
}
</View>
</Right>
</CardItem>
</View>
</TouchableOpacity>
);
}}
/>
</View>
</View>
}

use
keyboardShouldPersistTaps='always'
on parent components to the TouchableOpacity inorder for child touchables to persist the taps.
for eg1
<Flatlist keyboardShouldPersistTaps='always'>
<TouchableOpacity/>
</Flatlist>
eg2:
<TouchableOpacity keyboardShouldPersistTaps='always'>
<TouchableOpacity></TouchableOpacity>
</TouchableOpacity>

This, most probably, is a conflict between react components. While updating to latest react might do the trick, but I would advice you to try and remove each and every component and see if it works.
Are you using PanResponder by any chance? This could also create a conflict. Thanks and good luck.

Try react-native 0.55.4 its a stable version and i mostely use in my personal projects.
and try to wrap your image inside a View like this\
<TouchableOpacity>
<View>
<Image />
</View>
</TouchableOpacity>

You have 2 onPress nested functions, in <TouchableOpacity> and <Card>, which both are calling the same item, delete onPress function of <Card> component and it will mostly work

Related

How to resolve the Virtualized Lists warning with multiple Flatlists within a scroll

I have been working my way through legacy views within an app - resolving the issues of FlatLists within a ScrollView component casuing the resulting Virtualised Lists error that is displayed.
I have 5 affected pages - first 3 only had 1 flatlist in the view - so was easy enough to split the urrounding code into flatlist header and footer assets. However I'm not sure what to do in terms of having 2 or more flatlists - how do i apprach the layout in thsi scenario - so there is only 1 scroll?
I may be missing something very simple but need a nudge please!
here is the view code:
<View style={[PRStyles.IRContainer]} >
<StatusBar barStyle="light-content" />
<View style={PRStyles.header}>
<FixedHeader backButton={true} navScreen='HomeViewContainer' />
</View>
<View style={PRStyles.IRBody}>
<ScrollView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh} />}>
<KeyboardAvoidingView>
<TitleHeader sectionLocaleTxt='Duty Record' sectionTxt='' sectionDesc='End of shift duty Record.' sectionHyphen={false} />
<View style={FormStyles.PrRow}>
<Text style={FormStyles.PrRowTitle}>{this.props.auth.checkedInVenueName}</Text>
<Text style={FormStyles.PrRowDate}>{this.getCurrentDate()}</Text>
</View>
<View style={FormStyles.PrRow}>
<Text style={FormStyles.PrRowSubTitle}>General Manager / Licence Holder:</Text>
<View style={FormStyles.PrTable}>
<View style={FormStyles.prRowStrip}><Text style={FormStyles.prRowStripText} >{this.state.licenceHolder}</Text></View>
</View>
</View>
<View style={FormStyles.PrRow}>
<Text style={FormStyles.PrRowSubTitle}>Door Staff (<Text style={FormStyles.PrRowCount}>{this.state.doorStaffCount}</Text> total)</Text>
<View style={FormStyles.PrTable}>
<FlatList
scrollEnabled={true}
data={this.state.rotaRecords}
keyExtractor={(item, index) => index.toString()}
ListEmptyComponent={this._listStaffEmptyComponent}
renderItem={this._renderDoorStaffItem}
/>
</View>
</View>
<View style={FormStyles.PrRow}>
<Text style={FormStyles.PrRowSubTitle}>Numbers:</Text>
<View style={FormStyles.PrTable}>
<View style={FormStyles.prRowStrip}><Text style={FormStyles.prRowStripText} >Total In <Text style={ FormStyles.prRowStripColon}>:</Text> <Text style={FormStyles.prRowStripOrText}>{this.state.totalIn}</Text></Text></View>
<View style={FormStyles.prRowStrip}><Text style={FormStyles.prRowStripText} >Total Out<Text style={FormStyles.prRowStripColon}>:</Text> <Text style={FormStyles.prRowStripOrText}>{this.state.totalOut}</Text></Text></View>
<View style={FormStyles.prRowStrip}><Text style={FormStyles.prRowStripText} >Overall Difference<Text style={FormStyles.prRowStripColon}>:</Text> <Text style={FormStyles.prRowStripOrText}>{this.state.totalDifference}</Text></Text></View>
</View>
</View>
<View style={FormStyles.PrRow}>
<Text style={FormStyles.PrRowSubTitle}>Door Counts:</Text>
<FlatList
scrollEnabled={true}
data={this.state.countRecords}
keyExtractor={(item, index) => index.toString()}
ListEmptyComponent={this._listDoorCountEmptyComponent}
ListHeaderComponent={this._listDoorCountHeaderComponent}
renderItem={this._renderDoorCountItem}
/>
</View>
<View style={[FormStyles.form, FormStyles.PrRow, {marginTop:15, paddingTop:0, borderBottomWidth:0} ]}>
<Text style={ModalStyles.formTop}><Text style={[ModalStyles.required, ]}>*</Text>Required Field</Text>
<Text style={[FormStyles.formLabel, FormStyles.formlabelFirst ]}>1. Customer Comments:</Text>
<View style={FormStyles.textInputBlock}>
<TextInput
placeholder="Enter Comments"
numberOfLines={4}
onChangeText={val => this.setState({ comments: val})}
value={this.state.comments}
multiline
style={{minHeight: 280, height: 'auto', textAlignVertical: 'top'}}
/>
</View>
<Text style={[FormStyles.formLabel, FormStyles.formlabelFirst ]}>2. Duty Manager Name<Text style={ModalStyles.required}>*</Text> :</Text>
<View style={FormStyles.textInputBlock}>
<TextInput
ref='signatureName'
placeholder="Please Print Name"
style={FormStyles.textInputText}
autoCorrect={false}
returnKeyType='done'
value={this.state.signatureName}
onChangeText={(text) => this.setState({signatureName:text})}
/>
</View>
<Text style={[FormStyles.formLabel, FormStyles.formlabelFirst ]}>3. Duty Manager Signature: <Text style={ModalStyles.required}>*</Text></Text>
<Text style={[FormStyles.formLabelSub, FormStyles.formLabelSubHigh, FormStyles.superHighLight ]}>Note: PRESS BLUE SAVE BUTTON after applying Signature</Text>
<View style={[FormStyles.textInputBlock, this.isSignatureAdded() && FormStyles.signatureBlock ]}>
{this.signatureBlock()}
</View>
</View>
{submitButton}
</KeyboardAvoidingView>
</ScrollView>
</View>
</View>
This is the most common error when working with scroll view and flat list.
To prevent the error cause, we have to manage our views inside a single flat list and put other components in the list header component and list footer component in an efficient way as we desire.
<FlatList
data={this.state.countRecords}
renderItem={(item) => {
return (
// Your flat list item goes here..
)
}}
ListHeaderComponent={
// Content above the list goes here..
}
ListFooterComponent={
// Content below the list should goes here..
}
/>
You can still check the below link for more understanding.
FlatList Example with Custom Header and Custom Footer

React native Model popup with Check box list style Issue

I make check box list on Model Pop up by using react native multiple select checkbox list listed but it take full screen height i am not able to fix this issue please Any body help me
below is my Model Pop up Code
[![<Modal
animationType="slide"
transparent={true}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.ModalcenteredView}>
<View style={styles.ModalView}>
<View style={{height:'30%'}}>
<SelectMultiple
items={this.state.ParticipantCheckBox}
// renderLabel={renderLabel}
selectedItems={this.state.selectedFamilyMembers}
onSelectionsChange={this.SelectFamilyMembers} />
</View>
<View style={{flex:1, flexDirection:'row', flex:1,height:'1%'}}>
<TouchableHighlight style={{height:'5%'},\[styles.ModalCloseButton\] }
onPress={() => {
this.HideShowFamilyMemberModel(false);
}}
>
<Text style={styles.ModalCloseButtonTextStyle}>Close</Text>
</TouchableHighlight>
<TouchableHighlight style={{height:'5%'},\[styles.ModalSaveButton\] }
onPress={() => {
this.SaveFamilyMemberModel(false);
}}
>
<Text style={styles.ModalSaveButtonTextStyle}>Save</Text>
</TouchableHighlight>
</View>
</View>
</View>
</Modal>][1]][1]
You can make your modal like this
<Modal>
//this is parent view
<View>
//set this vide at the center of parent view and set height 40% or 30%
<View>
<ScrollView>
…
...
</ScrollView>
</View>
</View>
</Modal>

Text not getting rendered for an object

I have this below code, The alert shows following message:
{"item":{"isPositive":"false", "balance":"-500","currency":"AUD"}}
If I do alert on "ob" I get undefined. My problem is that the Text doesn't display anything:
_renderItemView(item) {
const ob = item
//alert(JSON.stringify(ob))
alert(JSON.stringify(item))
return(<>
<View style={styles.rowContainer}>
<View style={styles.iconContainer}></View>
<View style={styles.descriptionContainer}>
<Text style={styles.subText}>{item.date}asasas</Text>
{/* <Text style={styles.transactionDescText}>{item.description}</Text>
<Text style={styles.subText}>{item.descFrom}</Text> */}
</View>
<View style={styles.balanceContainer}>
{/* <Text style={styles.balance}>{item.currency}</Text>
<Text style={styles.balanceSubText}>{item.balance}</Text> */}
</View>
</View>
</>)
}
I was using renderItem={(item, index) => _renderItemView(item) to render
I needed an extra brace like this
renderItem={({item, index}) =>

How can I achieve this modal design with react native

I am trying design like below image with react native.If anyone have worked like this modal design over the toolbar then please help me.
1
You will need a Modal with a embedded TouchableOpacity combined with some styling for positioning.
Please refer this
https://snack.expo.io/SJrDAC8Qr
render() {
return (
<>
<View>
<Appbar.Header>
<Appbar.Content title="Title" subtitle="Subtitle" />
<Appbar.Action icon="search" onPress={() => this.setState({displayModal: true})} />
</Appbar.Header>
<View>
<Text>Main content!</Text>
</View>
</View>
{/*Modal code*/}
<Modal transparent={true} visible={this.state.displayModal}>
{/*Container .. clicking this closes the modal*/}
<TouchableOpacity style={{flex:1}} onPress={() => this.setState({displayModal:false})}>
<View style={{backgroundColor:'blue', position:'absolute', right:0, width:200, height: 200}}>
<Text style={{color:'#ffffff'}}>Hello World!</Text>
</View>
</TouchableOpacity>
</Modal>
</>
);
}
Not very nicely styled but I guess it does what you want

Double Tap Button issue when keyBoard opens React native

I know there are already so many queries on this topic, I have tried every step but still won't be able to fix the issue.
Here is the code :
render() {
const {sContainer, sSearchBar} = styles;
if (this.props.InviteState.objectForDeleteList){
this.updateList(this.props.InviteState.objectForDeleteList);
}
return (
<View style={styles.mainContainer}>
<CustomNavBar
onBackPress={() => this.props.navigation.goBack()}
/>
<View
style={sContainer}
>
<ScrollView keyboardShouldPersistTaps="always">
<TextInput
underlineColorAndroid={'transparent'}
placeholder={'Search'}
placeholderTextColor={'white'}
selectionColor={Color.colorPrimaryDark}
style={sSearchBar}
onChangeText={(searchTerm) => this.setState({searchTerm})}
/>
</ScrollView>
{this.renderInviteUserList()}
</View>
</View>
);
}
renderInviteUserList() {
if (this.props.InviteState.inviteUsers.length > 0) {
return (
<SearchableFlatlist
searchProperty={'fullName'}
searchTerm={this.state.searchTerm}
data={this.props.InviteState.inviteUsers}
containerStyle={styles.listStyle}
renderItem={({item}) => this.renderItem(item)}
keyExtractor={(item) => item.id}
/>
);
}
return (
<View style={styles.emptyListContainer}>
<Text style={styles.noUserFoundText}>
{this.props.InviteState.noInviteUserFound}
</Text>
</View>
);
}
renderItem(item) {
return (
this.state.userData && this.state.userData.id !== item.id
?
<TouchableOpacity
style={styles.itemContainer}
onPress={() => this.onSelectUser(item)}>
<View style={styles.itemSubContainer}>
<Avatar
medium
rounded
source={
item.imageUrl === ''
? require('../../assets/user_image.png')
: {uri: item.imageUrl}
}
onPress={() => console.log('Works!')}
activeOpacity={0.7}
/>
<View style={styles.userNameContainer}>
<Text style={styles.userNameText} numberOfLines={1}>
{item.fullName}
</Text>
</View>
<CustomButton
style={{
flexWrap: 'wrap',
alignSelf: 'flex-end',
marginTop: 10,
marginBottom: 10,
width: 90,
}}
showIcon={false}
btnText={'Add'}
onPress={() => this.onClickSendInvitation(item)}
/>
</View>
</TouchableOpacity> : null
);
}
**I even tried with bellow code as suggested by #Nirmalsinh **:
<ScrollView keyboardShouldPersistTaps="always" style={sContainer}>
<CustomNavBar
onBackPress={() => this.props.navigation.goBack()}
/>
<TextInput underlineColorAndroid={'transparent'}
placeholder={'Search'}
placeholderTextColor={'white'}
selectionColor={Color.colorPrimaryDark}
style={sSearchBar}
onChangeText={(searchTerm) => this.setState({searchTerm})} />
{this.renderInviteUserList()}
</ScrollView>
I have followed this article:
https://medium.com/react-native-training/todays-react-native-tip-keyboard-issues-in-scrollview-8cfbeb92995b
I have tried with keyboardShouldPersistTaps=handled also but still, I have to tap twice on my Custom Button to perform an action. Can anybody tell me what I am doing wrong inside the code?
Thanks.
You need to add give value always in keyboardShouldPersistTaps to allow user tap without closing the keyboard.
keyboardShouldPersistTaps='always'
For example:
<ScrollView keyboardShouldPersistTaps='always'>
// Put your component
</ScrollView>
NOTE: Kindly put your tappable component inside the ScrollView. Otherwise it won't work.
You can use keyboardShouldPersistTaps='handled' in a ScrollView or Scrollables like FlatList SectionList etc. and embed a TouchableWithoutFeedBack to handle the case for dismiss on outside clicks.
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<ScrollView keyboardShouldPersistTaps='handled'>
// Rest of the content.
</ScrollView/>
</TouchableWithoutFeedback>
For FlatList and SectionList you will have to handle KeyBoard.dismiss separately.
Please try this, It's working for me, it will works you also, i hope it helps...