I am using react-native-awesome-alerts plugin to show an alert in my screen. I've created a custom view for the alert but it throws me this error
Cannot add a child that doesn't have a YogaNode to a parent without a measure function! (Trying to add a 'RCTRawText [text: }]' to a 'RCTView')
My code is like this :
_displayNotifyAlert(){
if(this.state.notifyAlert == true){
return (
<AwesomeAlert
show={true}
title="Service Cancellation"
message="Tell the shop why are you cancelling their services."
messageStyle={{ textAlign: 'center' }}
customView={this.renderCustomAlertView()}
showCancelButton={true}
showConfirmButton={true}
cancelText="Cancel"
confirmText="Cancel Service"
confirmButtonColor={Colors.default}
onCancelPressed={() => this._closeNotifyAlert()}
onConfirmPressed={() => this._cancelServices()}
/>
)
}
}
renderCustomAlertView = () => (
<View style={[ AppStyles.input ]}>
<TextInput
placeholder="Write your reason briefly."
underlineColorAndroid="transparent"
style={{ textAlignVertical: 'top', height: 100 }}
numberOfLines={5}
multiline={true}
maxLength={200}
onChangeText={(cancel_reason) => this.setState({cancel_reason})} />
}
</View>
)
If I remove this line customView={this.renderCustomAlertView()}, the error will disappear. I don't see any incorrect code that I put in the renderCustomAlertView function. So I cannot track down the cause of the error. Is there anybody that faced the same problem before?
There's an extra "}" at the end of your renderCustomAlertView function. Change this function to the following and it should work:
renderCustomAlertView = () => (
<View style={[ AppStyles.input ]}>
<TextInput
placeholder="Write your reason briefly."
underlineColorAndroid="transparent"
style={{ textAlignVertical: 'top', height: 100 }}
numberOfLines={5}
multiline={true}
maxLength={200}
onChangeText={(cancel_reason) => this.setState({cancel_reason})} />
</View>
)
I can't comment in your post because of low reputations so I'm making it as an answer.
As per my knowledge in react native and based on your code You are missing return in renderCustomAlertView .
so your code must be something like
renderCustomAlertView = () => {
return(
<View style={[ AppStyles.input ]}>
<TextInput
placeholder="Write your reason briefly."
underlineColorAndroid="transparent"
style={{ textAlignVertical: 'top', height: 100 }}
numberOfLines={5}
multiline={true}
maxLength={200}
onChangeText={(cancel_reason) => this.setState({cancel_reason})} />
</View>
)
}
Related
I'm trying to delete the top, right and left borders of my textInput (so obviously, I'd like to have just the bottom border :) ) with the package react-native-autocomplete-input
I tried borderTop : 0 / and 'transparent' but it's not working I still have the borders on top and sides.
borderStyle didn't work either
I get this:
https://zupimages.net/viewer.php?id=20/03/ovck.bmp
my code is this:
<ScrollView style={styles.containerScroll}>
<Text style={styles.h1}>{i18n.t("tripsform.title")}</Text>
<Autocomplete
containerStyle={styles.container}
inputContainerStyle={styles.inputContainer}
autoCapitalize="none"
autoCorrect={false}
data={this.findAirports(query_arrival)}
defaultValue={this.findAirports(query_start)}
onChangeText={text => this.setState({ query_start: text })}
placeholder="Enter Start airports"
renderItem={({ airport }) => (
<TouchableOpacity
onPress={() => this.setState({ query_start: airport })}
>
<Text style={styles.h2}>{airport}-</Text>
</TouchableOpacity>
)}
/>
<Autocomplete
containerStyle={styles.container}
inputContainerStyle={styles.inputContainer}
autoCapitalize="none"
autoCorrect={false}
data={this.findAirports(query_arrival)}
defaultValue={this.findAirports(query_arrival)}
onChangeText={text => this.setState({ query_arrival: text })}
placeholder="Enter Arrival airports"
renderItem={({ airport }) => (
<TouchableOpacity
onPress={() => this.setState({ query_arrival: airport })}
>
<Text style={styles.h2}>{airport}-</Text>
</TouchableOpacity>
)}
/>
<Form ref={c => (this._form = c)} type={Trip} options={options} />
<Text>{"\n"}</Text>
<Text>{"\n"}</Text>
<Button
containerStyle={[styles.mybtnContainer]}
style={styles.mybtn}
onPress={this.handleSubmit}
>
{i18n.t("tripsform.item.add").toUpperCase()}
</Button>
<Button
onPress={() => this.props.navigation.navigate("MyTrips")}
containerStyle={[styles.mybtnContainer]}
style={styles.mybtn}
>
Return to my trips
</Button>
<Text>
{"\n"}
{"\n"}
</Text>
</ScrollView>
with this style:
inputContainer: {
minWidth: 300,
width: "90%",
height: 55,
backgroundColor: "transparent",
color: "#6C6363",
fontSize: 18,
fontFamily: "Roboto",
borderBottomWidth: 1,
borderBottomColor: "rgba(108, 99, 99, .7)"
},
If I can get any help that's really nice, thanks for reading and for any help !
You need to use inputContainerStyle property to apply styles to the input.
You can also use containerStyle to style the container around the AutoComplete so you also don't need to wrap the Autocomplete with View tag.
<Autocomplete
inputContainerStyle={styles.inputContainer}
/>
This Should give you the desired output :) :
<Autocomplete
inputContainerStyle={{width:"100%",borderBottomWidth:1}}
inputStyle={{borderWidth:0}}
data={Options}
handleSelectItem={(item,id)=>optionHandler(item.value,id)}
valueExtractor={item => item.value}
/>
It seems that it's impossible with that package.
I could do what I wanted to do with 'native base autocomplete'.
So, it doesn't completely answer the question but it allows you to do the right thing!
You can set the inputContainer style borderWidth to 0:
// other styles
inputContainer: {
borderWidth: 0,
},
I am trying to implement the modal component in this app and for some reasons, I cant make it work. I have done it in another app and even though everything looks as it should in this one, it still doesn't work, it just doesn't toggle!
Here is my code (i call toogleModal() here ):
<TouchableOpacity
activeOpacity={1}
style={styles.slideInnerContainer}
//onPress={() => { alert(`You've clicked '${rest_name}'`); }}
onPress={() => this.toggleModal(rest_name)}
>
<View style={styles.shadow} />
<View style={[styles.imageContainer, even ? styles.imageContainerEven : {}]}>
{this.image}
<View style={[styles.radiusMask, even ? styles.radiusMaskEven : {}]} />
</View>
<View style={[styles.textContainer, even ? styles.textContainerEven : {}]}>
<View style={{ flexDirection: 'row' }}>
{uppercaseTitle}
{ratings}
</View>
<Text
style={[styles.subtitle, even ? styles.subtitleEven : {}]}
numberOfLines={2}
>
{rest_location}
</Text>
</View>
</TouchableOpacity>
Now here is the toggleModal() which should set the state and then call the onPressItem() :
toggleModal = (item) => {
this.setState({ isModalVisible: !this.state.isModalVisible });
this.onPressItem(item);
};
and onPressItem() :
onPressItem = (item) => {
return (
<ThemeProvider theme={theme}>
<Modal animationIn="rubberBand" animationOut={"bounceOut"}
isVisible={this.state.isModalVisible}
onBackdropPress={() => this.setState({ isModalVisible: false })}
>
<View style={{ flex: 1 }}>
{item}
</View>
<View style={{ flex: 1 }}>
<Button title="Hide modal" onPress={this.toggleModal} />
</View>
</Modal>
</ThemeProvider>
)
};
Now, remember this code is taken from another app where modal is working perfectly!
Most probably your issue with click option is connected with incorrect import TouchableOpacity from correct module. Check if you are importing from react-native:
import { TouchableOpacity } from 'react-native';
change this line
onPress={() => this.toggleModal(rest_name)}
to this:
onPress={() => {this.toggleModal(rest_name)}}
you only need to put the function call in brackets
I am creating a render function to display information from within an array. Everything is functioning completely fine, however when I run the project I get an warning saying that each child in the list requires a unique key. I researched all the reasons why this may be happening however I don't see why I am getting this warning. Please help me.
Here is the entire code, from setting the data and rendering the function, thank you:
this.state = {
feed: [{
username: ["Its_Jess: ", "Animal_Luver: ", "Kyl3_Rayn3r: ", "Smith_Family: "],
caption: ["The New Photoshoot was so much fun!", "AWWWW Look at them sleep!!", "Beautiful swim", "This photo is from our vacation <3"],
coments: ["View All 49 Comments", "View All 19 Comments", "View All 69 Comments", "View All 4 Comments"],
photo:[Pic1,Pic2,Pic4,Pic6],
avatar:[Pic1,Ava1,Ava2,Ava3]
}]
}
renderFeed = () => {
return this.state.feed.map((card, index) => {
return card.username.map((username, i) => {
if(card.caption[i])
return (
<View>
<TouchableHighlight
onPress={()=>this.toggleModal({photo:card.photo[i], avatar:card.avatar[i] ,caption:card.caption[i],username:card.username[i],coments:card.coments[i]})}
underlayColor="white">
<Card
key={`${i}_${index}`}
image={card.photo[i]}
containerStyle={{borderRadius:10, marginRight:1, marginLeft:1,}}>
<View
style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}
>
<View style={{ flexDirection: 'row'}}>
<Avatar
key={card.avatar}
size="small"
rounded
source={card.avatar[i]}
/>
</View>
<View style={{flexDirection:'row'}}>
{this.state.isLiked[i] ?(
<Avatar
rounded
icon={{
name: 'heart-multiple-outline',
type: 'material-community',
}}
overlayContainerStyle={{
backgroundColor: '#ff4284',
marginLeft: 5,
}}
reverse
size="small"
onPress={()=> this.toggleLike(i)}/>
) : (
<Avatar
rounded
icon={{ name:'heart-multiple-outline', type:'material-community', color: '#ff4284'}}
overlayContainerStyle={{marginLeft:5}}
reverse
size='small'
onPress={()=> this.toggleLike(i)}/>
)}
<Avatar
reverse
rounded
icon={{ name:'comment-processing-outline', type:'material-community' }}
overlayContainerStyle={{backgroundColor: '#dbdbdb',marginLeft:5}}
size='small'/>
</View>
</View>
{ this.state.fontLoaded == true ? (
<View style={{flexDirection:'row'}}>
<Text style={{fontFamily: 'MontserratB', color:'#bf00b9', marginTop:10}} key={username}>{username}</Text>
<Text style={{fontFamily:'Montserrat', marginTop:10}} key={card.caption}>{card.caption[i]}</Text>
</View>
) : (<Text> Loading...</Text>)
}
<Text style={{marginTop:4, color:'#878787'}} key={card.coments}>{card.coments[i]}</Text>
</Card>
</TouchableHighlight>
</View>
);
return <React.Fragment />;
});
})
}
render(){
return (
<View>
{this.renderFeed()}
</View>
)}
The issue was in where I was declaring my key. I moved key={`${i}_${index}`} from the <Card> element up to the <View> element and now the warning is gone
It's always a good practice to assign each of the elements in the array with a unique key because Keys are necessary to improve performance of your React app. Please refer the below article to get the exact knowledge of why it's necessary.
Keys
I am using react-native TextInput component. Here I need to show the InputBox above the keyboard if the user clicks on the textInput field.
I have tried below but i am facing the issues
1. Keyboard avoiding view
a. Here it shows some empty space below the input box
b. Manually I need to scroll up the screen to see the input field which I was given in the text field
c. Input box section is hiding while placing the mouse inside the input box
2. react-native-Keyboard-aware-scroll-view
a.It shows some empty space below the input box
b.ScrollView is reset to the top of the page after I moving to the next input box
Here I set the Keyboard-aware-scroll-view inside the ScrollView component
Kindly clarify
My example code is
<SafeAreaView>
<KeyboardAvoidingView>
<ScrollView>
<Text>Name</Text>
<AutoTags
//required
suggestions={this.state.suggestedName}
handleAddition={this.handleAddition}
handleDelete={this.handleDelete}
multiline={true}
placeholder="TYPE IN"
blurOnSubmit={true}
style= {styles.style}
/>
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
[https://github.com/APSL/react-native-keyboard-aware-scroll-view]
Give your TextInput a position: absolute styling and change its position using the height returned by the keyboardDidShow and keyboardDidHide events.
Here is a modification of the Keyboard example from the React Native documentation for demonstration:
import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';
class Example extends Component {
state = {
keyboardOffset: 0,
};
componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
this._keyboardDidShow,
);
this.keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
this._keyboardDidHide,
);
}
componentWillUnmount() {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
_keyboardDidShow(event) {
this.setState({
keyboardOffset: event.endCoordinates.height,
})
}
_keyboardDidHide() {
this.setState({
keyboardOffset: 0,
})
}
render() {
return <View style={{flex: 1}}>
<TextInput
style={{
position: 'absolute',
width: '100%',
bottom: this.state.keyboardOffset,
}}
onSubmitEditing={Keyboard.dismiss}
/>
</View>;
}
}
First of all, You don't need any extra code for Android platform. Only keep your inputs inside a ScrollView. Just use KeyboardAvoidingView to encapsulate the ScrollView for iOS platform.
Create function such as below which holds all the inputs
renderInputs = () => {
return (<ScrollView
showsVerticalScrollIndicator={false}
style={{
flex: 1,
}}
contentContainerStyle={{
flexGrow: 1,
}}>
<Text>Enter Email</Text>
<TextInput
style={styles.text}
underlineColorAndroid="transparent"
/>
</ScrollView>)
}
Then render them inside the main view as below
{Platform.OS === 'android' ? (
this.renderInputs()
) : (
<KeyboardAvoidingView behavior="padding">
{this.renderInputs()}
</KeyboardAvoidingView>
)}
I have used this method and I can assure that it works.
If it is not working then there is a chance that you are missing something.
Hooks version:
const [keyboardOffset, setKeyboardOffset] = useState(0);
const onKeyboardShow = event => setKeyboardOffset(event.endCoordinates.height);
const onKeyboardHide = () => setKeyboardOffset(0);
const keyboardDidShowListener = useRef();
const keyboardDidHideListener = useRef();
useEffect(() => {
keyboardDidShowListener.current = Keyboard.addListener('keyboardWillShow', onKeyboardShow);
keyboardDidHideListener.current = Keyboard.addListener('keyboardWillHide', onKeyboardHide);
return () => {
keyboardDidShowListener.current.remove();
keyboardDidHideListener.current.remove();
};
}, []);
You can use a scrollview and put all components inside the scrollview and add automaticallyAdjustKeyboardInsets property to scrollview.it will solve your problem.
automaticallyAdjustKeyboardInsets Controls whether the ScrollView should automatically adjust its contentInset and
scrollViewInsets when the Keyboard changes its size. The default value is false.
<ScrollView automaticallyAdjustKeyboardInsets={true}>
{allChildComponentsHere}
<View style={{ height: 30 }} />//added some extra space to last element
</ScrollView>
Hope it helps.
you can use KeyboardAvoidingView as follows
if (Platform.OS === 'ios') {
return <KeyboardAvoidingView behavior="padding">
{this.renderChatInputSection()}
</KeyboardAvoidingView>
} else {
return this.renderChatInputSection()
}
Where this.renderChatInputSection() will return the view like textinput for typing message. Hope this will help you.
For android you can set android:windowSoftInputMode="adjustResize" for Activity in AndroidManifest file, thus when the keyboard shows, your screen will resize and if you put the TextInput at the bottom of your screen, it will be keep above keyboard
react-native-keyboard-aware-scroll-view caused similar issue in ios. That's when I came across react-native-keyboard-aware-view. Snippets are pretty much same.
<KeyboardAwareView animated={true}>
<View style={{flex: 1}}>
<ScrollView style={{flex: 1}}>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>A</Text>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>B</Text>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>C</Text>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>D</Text>
</ScrollView>
</View>
<TouchableOpacity style={{height: 50, backgroundColor: 'transparent', alignItems: 'center', justifyContent: 'center', alignSelf: 'stretch'}}>
<Text style={{fontSize: 20, color: '#FFFFFF'}}>Submit</Text>
</TouchableOpacity>
</KeyboardAwareView>
Hope it hepls
You will definitely find this useful from
Keyboard aware scroll view Android issue
I really don't know why you have to add
"androidStatusBar": {
"backgroundColor": "#000000"
}
for KeyboardawareScrollview to work
Note:don't forget to restart the project without the last step it might not work
enjoy!
I faced the same problem when I was working on my side project, and I solved it after tweaking KeyboardAvoidingView somewhat.
I published my solution to npm, please give it a try and give me a feedback! Demo on iOS
Example Snippet
import React from 'react';
import { StyleSheet, TextInput } from 'react-native';
import KeyboardStickyView from 'rn-keyboard-sticky-view';
const KeyboardInput = (props) => {
const [value, setValue] = React.useState('');
return (
<KeyboardStickyView style={styles.keyboardView}>
<TextInput
value={value}
onChangeText={setValue}
onSubmitEditing={() => alert(value)}
placeholder="Write something..."
style={styles.input}
/>
</KeyboardStickyView>
);
}
const styles = StyleSheet.create({
keyboardView: { ... },
input: { ... }
});
export default KeyboardInput;
I based my solution of #basbase solution.
My issue with his solution that it makes the TextInput jumps up without any regard for my overall view.
That wasn't what I wanted in my case, so I did as he suggested but with a small modification
Just give the parent View styling like this:
<View
style={{
flex: 1,
bottom: keyboardOffset,
}}>
And it would work! the only issue is that if the keyboard is open and you scrolled down you would see the extra blank padding at the end of the screen.
android:launchMode="singleTask"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
write these two lines in your android/app/src/main/AndroidManifest.xml
in activity tag
flexGrow: 1 is the key.
Use it like below:
<ScrollView contentContainerStyle={styles.container}>
<TextInput
label="Note"
value={currentContact.note}
onChangeText={(text) => setAttribute("note", text)}
/>
</ScrollView>
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
});
Best and Easy Way is to use Scroll View , It will Automatically take content Up and TextInput will not be hide,Can refer Below Code
<ScrollView style={styles.container}>
<View>
<View style={styles.commonView}>
<Image source={firstNameIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>First Name</Text>
</View>
<TextInput
onFocus={() => onFocus('firstName')}
placeholder="First Name"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'firstName')}
value={firstNameValue}
/>
</View>
<View>
<View style={styles.commonView}>
<Image source={LastNameIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>Last Name</Text>
</View>
<TextInput
onFocus={() => onFocus('lastName')}
placeholder="Last Name"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'lastName')}
value={lastNameValue}
/>
</View>
<View>
<View style={styles.commonView}>
<Image source={callIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>Number</Text>
</View>
<TextInput
onFocus={() => onFocus('number')}
placeholder="Number"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'number')}
value={numberValue}
/>
</View>
<View>
<View style={styles.commonView}>
<Image source={emailIcon} style={{width: 25, height: 25}}></Image>
<Text style={styles.commonTxt}>Email</Text>
</View>
<TextInput
onFocus={() => onFocus('email')}
placeholder="Email"
style={styles.txtInput}
onChangeText={(text) => onChangeText(text, 'email')}
value={emailValue}
/>
</View>
<View style={styles.viewSavebtn}>
<TouchableOpacity style={styles.btn}>
<Text style={styles.saveTxt}>Save</Text>
</TouchableOpacity>
</View>
</ScrollView>
go to your Android>app>src>main> AndroidManifest.xml
write these 2 lines :
android:launchMode="singleTop" android:windowSoftInputMode="adjustPan"
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...