ReactNative - KeyboardAvoidingView - reactjs

I have a page with two inputs and a 'Next' button. I want to move my container up when keyboard is active so that the 'Next' button is also visible when the keyboard is open. I've used KeyboardAvoidingView but the content is not moving when the keyboard is active. What seems to be the issue here?
Here is my code
<View style={{height: '100%'}}>
<LinearGradient colors={['#29aae1', '#4bc1b6']} style={{height: '100%'}}>
<KeyboardAvoidingView
behavior="padding"
keyboardVerticalOffset={0}
style={{padding:10}}
>
<ScrollView style={{height:'100%'}}>
<Text style={styles.signin_info}>Let's get you signed in. Provide your first name and last
name.
Do not
worry, when you comment your real name won't be visible ;)</Text>
<Field label="First name" name="signUpFirstName" component={this.renderInput}/>
<Field label="Last name" name="signUpLastName" component={this.renderInput}/>
<TouchableOpacity block primary style={styles.nextBtn_active}
onPress={Actions.signUp_email}><Text
style={{fontFamily: 'gotham', fontSize: 18, color: 'white'}}
allowFontScaling={false}>Next</Text></TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
</LinearGradient>
</View>

If you already ScrollView inside KeyboardAvoidingView, consider using react-native-keyboard-aware-scroll-view instead.

Your KeyboardAvoidingView component is not enabled !!! enabled property is mandatory:
<KeyboardAvoidingView
behavior="padding"
keyboardVerticalOffset={0}
style={{padding:10}}
enabled // <-- this property is required
>
See: enabled

Related

TextInput weird behaviour in React-Native

I have the following TextInput,
<TextInput
style={[
styles.inputField,
isEmailError && { borderColor: color.delete },
]}
placeholder={'E-mail'}
placeholderTextColor={color[colorScheme].textMuted}
autoCapitalize={'none'}
autoCorrect={false}
value={userCredentials.email}
onChangeText={onChangeEmail}
onSubmitEditing={passwordInput.current && passwordInput.current.focus}
blurOnSubmit={false}
returnKeyType={'next'}
keyboardType="email-address"
/>
When I click anywhere else outside the keyboard(let's say a button), the expected behaviour is that the button will get clicked, however, in here, first click always closes the keyboard then I have to press again for whatever element i was trying to reach.
This is because of scroll view. Add props keyboardShouldPersistTaps in your scrollview as below to solve error :
<ScrollView
keyboardShouldPersistTaps="handled"
keyboardDismissMode="interactive"
>
...
...
</ScrollView>
You can find more detail here
Maybe try this:
import DismissKeyboard from 'dismissKeyboard';
<TouchableWithoutFeedback onPress={()=>{DismissKeyboard()}}>
<View style={Styles.container}>
<TextInput />
</View>
</TouchableWithoutFeedback>

KeyboardAvoidingView doesn't work inside tab navigation

I'm using the built-in KeyboardAvoidingView in react native and when I use the code below in a screen where you can't see the tabs (like in a modal) it works perfectly fine and the keyboard doesn't cover any content whatsoever, but when I use the exact same code but in a screen that is used in tab navigation the keyboard covers some content, it's like the KeyboardAvoidingView doesn't take into consideration the height of the bottom tabs
Here's my code:
<KeyboardAvoidingView style={{flex: 1}} behavior="padding">
<ScrollView keyboardShouldPersistTaps="handled">
{content}
</ScrollView>
<TextInput
style={{height: 50, width: "100%", backgroundColor: "red"}}
placeholder="Test input"
/>
</KeyboardAvoidingView>

Each child in a list should have a unique "key" prop for <View> not working react native

I have a list for user details, in that for parent container I have given <View key={details.id}> an it is unique. But I loaded the page it always throws Warning: Each child in a list should have a unique "key" prop.. Also the TextInput fields are not editable. Wher am going wrong. Please have a look into my code.
{this.state.profileDetails.map(details => {
return (
<View key={details.id}>
<Text style={{textAlign: 'center'}}>
<Image
style={styles.imageCircle}
source={require('../../../../assets/sample.jpeg')}
/>
</Text>
<View>
<Text style={{marginBottom: 5}}>First Name:</Text>
<TextInput
style={styles.textEdit}
value={details.first_name}
onChangeText={(text) => this.setState({first_name:text})}
/>
<Text style={{marginBottom: 5}}>Last Name:</Text>
<TextInput
style={styles.textEdit}
value={details.last_name}
/>
<Text style={{marginBottom: 5}}>Title:</Text>
<TextInput
style={styles.textEdit}
value={details.designation}
/>
<Text style={{marginBottom: 5}}>Firm:</Text>
<TextInput
style={styles.textEdit}
value={details.firm}
/>
<Text style={{marginBottom: 5}}>Email Address:</Text>
<TextInput
style={styles.textEdit}
value={details.email}
/>
<Text style={{marginBottom: 5}}>Work Number:</Text>
<TextInput
style={styles.textEdit}
value={details.work_number}
/>
<Text style={{marginBottom: 5}}>Cell Number:</Text>
<TextInput
style={styles.textEdit}
value={details.cell_number}
/>
<Text style={{marginBottom: 5}}>LinkedIn Profile:</Text>
<TextInput
style={styles.textEdit}
value={details.linkedin_profile}
/>
<Text style={{marginBottom: 5}}>Summary:</Text>
<TextInput
multiline={true}
numberOfLines={4}
style={styles.textEdit}
value={details.about}
/>
</View>
</View>
)
})}
Is there any solution to bypass this issue. Please guide me through.
most probably you details may not have id field, due to which each time it gets undefined value and repeated through out you other children, the quick fix could be to use index that map gives as second parameter
[].map((currentValue, index) => {});
about TextField, see you haven't told the TextField component to do something when a user edits to change it's value due to which the value is not being updated and hence the old value pops up which makes it seem like its not editable , please refer documentation to see the props that are required, https://facebook.github.io/react-native/docs/textinput.html
Try to use array index for the key instead
{this.state.profileDetails.map((details, index) => //... )}
But keep in mind it's not the best for performance if the item order changes frequently. I would still suggest trying to make unique identifiers like the id field work and use those instead.
https://reactjs.org/docs/lists-and-keys.html#keys

react native Scroll View doesn't scroll from inside text input

I added multi Text input inside a scroll view. the problem is when I want to scroll down from inside of a text input, I put my finger inside a text input and scroll down but it doesn't scroll down the page, is there a way to fix this?
here is a sample code:
export default class ScrollViewWithTextInput extends React.Component {
render() {
<ScrollView>
<TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/>
<TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/><TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/><TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/>
<TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/>
<TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/><TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/><TextInput
style={styles.input}
placeholder={'توضیحات'}
underlineColorAndroid='transparent'
/>
</ScrollView>
}}
const styles = StyleSheet.create({
Container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
marginTop: 8
},
input: {
width: 350,
height: 100,
margin: 5,
borderColor: 'black',
borderWidth: 2,
textAlign: 'right'
}})
For some reason setting multiline={true} to the TextInput worked for me.
Not exactly sure why. Stranger still, it will not work if you also have keyboardType='numeric'.
Use each input as a component. try something like this:
<TouchableOpacity onPress={()=>this.input.focus()} >
<View pointerEvents="none" >
<TextInput ref = {(input) => this.input = input} />
</View>
</TouchableOpacity>
This will do the trick
Try to adjust the height of the input.
I don't really understand why but it solved my problem.
setting
<ScrollView keyboardShouldPersistTaps="always"
in combination with the textInout component below (custom component that i created for text inputs to solve this issue) solved my problem:
<TouchableOpacity
activeOpacity={1}
onPress={()=>this.input.focus()}>
<View
pointerEvents="none">
<TextInput
ref = {(input) => this.input = input}
/>
</View>
</TouchableOpacity>
Update
a better expression might be:
constructor(props) {
super(props);
this._keyboardDidHide = this._keyboardDidHide.bind(this)
this.onSubmitEditing = this.onSubmitEditing.bind(this)
}
componentWillMount () {
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide)
};
componentWillUnmount () {
this.keyboardDidHideListener.remove();
}
_keyboardDidHide(){
this.input.blur()
}
and then the expression above for the TextInput component. because in the previous expression when you press back and the keyboard hides, and you tap on that input again, the keyboard doesn't open, because that input is already focused. so you need to blur and then focus again.
this is my idea, maybe you might perform this in a more creative way :)
btw don't forget to import Keyboard from 'react-native' if you use my expression.

React Native, scrolling TextInput behind a ToolbarAndroid

I've been stuck on the following issue for awhile now. I have a ToolbarAndroid component and a TextInput component:
<View style={{flex: 1}}>
<ToolbarAndroid
navIcon={require('./ic_menu_black_24dp.png')}
onIconClicked={() => this.drawer.openDrawer()}
style={styles.titleView}
title="Blah"
titleColor="black"
/>
<ScrollView>
<TextInput
{...this.props}
multiline={true}
onChange={(event) => {
this.setState({
text: event.nativeEvent.text,
height: event.nativeEvent.contentSize.height,
color: 'black'
});
}}
style={{fontSize: 14, textAlignVertical: 'top', height: Math.max(60, this.state.height)}}
value={this.state.text}
placeholder="Spread your message!"
placeholderTextColor='lightslategray'
underlineColorAndroid='white'
enablesReturnKeyAutomatically={true}
returnKeyType="done"
maxLength={1000}
/>
</ScrollView>
</View>
My TextInput box is auto-expanding which means it grows as it types. The input also re-focuses on top of the keyboard as it grows. However, as it grows to be bigger than my screen, it doesn't scroll behind the Toolbar. Instead, it pushes the toolbar off the screen. I'd like it to scroll behind the toolbar but I can't seem to get it to work.
Any help would be greatly appreciated.
Thanks

Resources