Open peacechen opened 7 years ago
I have a similar issue
node: 8.9.1 react: 16.0.0 react-native: 0.50.3 yarn: 1.3.2 watchman: 4.9.0 xcode: 9.1
<TextInput>
component with autoCorrect="false"
prop.behavior="position"
prop.Multiline TextInput should be above the soft keyboard.
Soft keyboard covers TextInput.
Keyboard.addListener('keyboardWillChangeFrame', this.onKeyboardChange)
doesn't`t fire when I change keyboard to emoji and fires when I change from emoji to other
KeyboardAvoidingView works fine with multiline TextInput because i am using them myself. Initially they would not work for me. To solve my problem i removed the height on the TextInput and set the behavior to "padding". The "flex: 1" you have on the KeyboardAvoidingView might be the problem i think or its the scrollview. But KeyboardAvoidingView definitely works fine with multiline.
Referring to my snippet posted above, there's no height on the TextInput, and KeyboardAvoidingView's behavior is set to padding.
Its style needs flex:1
to allow the ScrollView to take up the entire height.
Try the code with and without multiline set. It fails with multiline set, but the same code works for single line TextInputs.
Same problem here!
@peacechen I have exactly the same problem like you. Need to add flex: 1 for the ScrollView as the wrapper. And it works if I remove the prop multiline={true}. Any solution for this?
The same issue。 my code is same as the author. there is a multiline TextInput in ScrollView. outsider with a KeyboardAvoidingView wrapper.
If anyone still is looking for a fix, you could try
<View style={{position:relative}}>
<TextInput ref='multilineText' value={this.state.textValue}
onChangeText={(textValue) => this.setState({textValue})}/>
<TextInput style={{ color:'transparent', position: 'absolute', width: '100%', height: '100%' }}
placeholderTextColor='transparent'
onFocus={() => setTimeout(() => this.refs.multilineText.focus(), 1000) }
value={this.state.textValue}
onChangeText={(textValue) => this.setState({textValue})}
/>
</View>
Its a dirty hack but it does the job, what it does it when user clicks on the input it would be clicking on the single line and the keyboard will scroll to that line then after 1 seconds (you can adjust this, i just found 1 seconds to be good with our app) it would focus on the multiline. The value and onChangeText makes sure that when the user star typing they would have the same value except the single line has transparent text.
The downside is when a user clicked the multiple line, the cursor wont go to the location they clicked but it would go to the end.
@monmonja That's a creative work-around. I wonder if it could also be done by setting the multiline
prop to a state variable that is changed during onFocus
. That would eliminate the second TextInput
.
I don't see the multiline prop in the first TextInput, but I assume it's supposed to be in there.
Has anyone found a good solution for this?
@peacechen I tried to implement your suggestion but it has a strange effect and doesn't work. Something's flickering and the keyboard eventually disappears. I am also looking for a solution to this. Cannot apply @monmonja 's workaround because I'm using redux-form. This makes it much more complicated for this workaround. I can confirm that all is working fine when I remove the multiline prop. I wrapped the whole application with KeyboardAvoidingView and my multiline TextInput is at the end of the form like in the author's example. I have no height applied to the TextInput which in a few cases can cause issues. I am using react-native: 0.53.0
same problem here and still have no solution
I too facing the same issue. It works fine if multiline is set to false and not if set to true. My TextInput does not have any height. Any solutions??
A workaround for this is to make a reference to the parent scrollview and call its scrollTo method to the multilined TextInput coordinates whenever onFocus is called.
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior="padding"
>
<ScrollView ref={component => { this.myScrollView = component; }}>
<TextInput
multiline
onFocus={() => this.myScrollView.scrollTo({ x: 0, y: 750, animated: true })} // <- your coordinates here
/>
</ScrollView>
</KeyboardAvoidingView>
same problem here only on IOS textinput multiline has no effect on keyboardavoidingview
it is working fine on android
This has been quite frustrating for us as well.. Seems like the only consistent way to do this is by scrolling manually as @jasonchoibiz suggested.
It's an ugly workaround though! ☹️
there is news about this problem?
Still having this. Tried the suggested solutions.
same problem here
Same issue, here's a simple snack for anyone to play with: https://snack.expo.io/r1qpj0k5Q
Same issue, here's a simple snack for anyone to play with: https://snack.expo.io/r1qpj0k5Q
I've tried this and it works:
react-native version 0.56.1 same problem....
it is working;
<KeyboardAvoidingView behavior="padding" style={Platform.OS !== 'android' && { flex: 1 }}>
<ScrollView>
...
<TextInput ... />
...
</ScrollView>
</KeyboardAvoidingView>
@recepkoseoglu It works on non-multiline Inputs. Try on multiline.
It's working if we use <View>
to wrap the content instead of <ScrollView>
, not ideal if you have many TextInputs though.
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : null}
style={{ flex: 1 }}
>
<View style={{ flex: 1, justifyContent: "flex-end" }}>
...
<TextInput multiline />
<View style={{ flex: 1 }} /> // Use this to take up bottom spacing
</View>
</KeyboardAvoidingView>
No fix yet?
RN 0.57... confirm same issue.
still same issue here. any solution?
I switched to "React-Native Keyboard Manager" and it works. Just install and your issues are solved
This is really causing a lot of problems. Any updates on this issue? I have tried using the libraries mentioned above but each of them come with sacrifices in user experience.
Same here. With multiline applied, KeyboardAvoidingView doesn't work.
Just hit this exact problem, and can confirm that KeyboardAvoidingView has no effect at all with any behaviour attribute option if the View contains a multiline TextInput
Super annoying. Any resolve here?
I tried to debug this today without much success. What I found out however is that _onKeyboardChange is triggered no matter if we have a multiline true or false. In both cases LayoutAnimation receives the same config: https://github.com/facebook/react-native/blob/master/Libraries/Components/Keyboard/KeyboardAvoidingView.js#L107
I added an onAnimationDidEnd callback to LayoutAnimatijon and it has been called both for multiline true and false. In the case of false - the view was properly updated. In the case of multiline true as per the issue here - no layout change occurs.
So it seems that the KeyboardAvoidingView component behaves correctly both for multiline true or false, but LayoutAnimation fails to properly animate the position with multiline true.
KeyboardAvoidingView works fine with multiline TextInput because i am using them myself. Initially they would not work for me. To solve my problem i removed the height on the TextInput and set the behavior to "padding". The "flex: 1" you have on the KeyboardAvoidingView might be the problem i think or its the scrollview. But KeyboardAvoidingView definitely works fine with multiline.
Kinda feel weird to be the only person upvoting this one, but simply setting behavior to position
worked for me!
If you want to KeyboardAvoidingView works fine with multiline TextInput, please setting the scrollEnabled prop of TextInput to false. It works for me.
If you want to KeyboardAvoidingView works fine with multiline TextInput, please setting the scrollEnabled prop to false. It works for me.
It works for me, too
@bob76828 Thanks for saving my time.
Does setting scrollEnabled={false}
for KeyboardAvoidingView work inside a ScrollView? Refer to the OP for how it's used in such a case.
@peacechen You should use ScrollView inside KeyboardAvoidingView
<KeyboardAvoidingView>
<ScrollView>
<TextInput
multiline={true}
scrollEnabled={false} // to make keyboard avoiding works
>
</TextInput>
</ScrollView>
</KeyboardAvoidingView>
Referring to my snippet posted above, there's no height on the TextInput, and KeyboardAvoidingView's behavior is set to padding.
Its style needs
flex:1
to allow the ScrollView to take up the entire height.Try the code with and without multiline set. It fails with multiline set, but the same code works for single line TextInputs.
^ This from @peacechen worked for me perfectly. I have scrollEnabled={true}
& multiline={true}
Code:
<KeyboardAvoidingView
behavior="padding"
style={{flex: 1, flexDirection: "column"}}
>
<View style={{flex: 1}}>
<TextInput
multiline={true}
scrollEnabled={true}
style={{flex:1}}
// Other relevant props
/>
</View>
<KeyboardAvoidingView />
scrollEnabled={false} // to make keyboard avoiding works
Yep, but if this option enabled with eg numberOfLines={3}, we have multiline textinput without scrolling which is not so good for forms with lots of other fields
@adteague the problem persists when you have a scrollview inside the KeyboardAvoidingView instead of a simple view
@gbalduzzi You don't add a ScrollView component. You make the TextInput multiple lines with scrolling enabled. See my code example above.
@adteague A ScrollView is needed when the form is longer than the screen height. Multiple TextInputs live within the ScrollView. Does your approach solve that use case?
@peacechen No it would not. Try...
<KeyboardAvoidingView
behavior="height"
style={{flex: 1, flexDirection: "column"}}
>
<ScrollView style={{flex: 1}}>
<TextInput
multiline={false} // Default is false so you can remove this line
scrollEnabled={false} // Default is false so you can remove this line
style={{flex: 0}}
// Other relevant props
/>
<TextInput
style={{flex: 0}}
// Other relevant props
/>
</ScrollView>
<KeyboardAvoidingView />
(Not on my dev computer so sorry if it doesn't works)
That's the same structure as the code snippet in the OP, which results in the multiline TextInput bug.
Edit: I haven't had the opportunity to test out your code snippet a few posts prior. It looks like yours works because it's not in a ScrollView.
@adteague My whole screen is wrapped by a KeyboardAvoidingView and, inside that, I have a Scrollview because the content is long and need to be scrolled.
At the end of the screen, I have a multiline textinput. On iOS, when the user tap on the text input it opens the keyboard without moving the input. If I set multiline={false}
, it works perfectly.
The overall structure is the following:
<SafeAreaView style={{flex: 1}}>
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : null} style={{flex: 1}}>
<ScrollView style={{flex: 1}} contentContainerStyle={{flexGrow: 1}}>
// Some other stuff
<TextInput style={{width: 200, height: 300}} multiline={true} scrollEnabled={false} />
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
@gbalduzzi try doing this way:
<KeyboardAvoidingView
enabled
behavior={ Platform.OS === 'ios' ? 'padding' : false }
style={{ flex: 1}}
>
<ScrollView
keyboardShouldPersistTaps={'always'}
keyboardDismissMode={ Platform.OS === 'ios' ? 'interactive' : 'on-drag'}
>
<TextInput style={{width: 200, height: 300}} multiline={true} scrollEnabled={false} />
</ScrollView>
</KeyboardAvoidingView>
Keyboard will not overlap multiline TextInput, so you can scroll and edit text. It will hide on swipe to top in interactive mode on iOS, but KeyboardAvoidingView will not scroll to multiline TextInput. Android should be ok.
If you want to KeyboardAvoidingView works fine with multiline TextInput, please setting the scrollEnabled prop of TextInput to false. It works for me.
This one worked for me! Thanks @bob76828
KeyboardAvoidingView only works with single-line TextInputs. When the
multiline
prop is set, KeyboardAvoidingView does not shift the TextInput at all.Is this a bug report?
Yes
Have you read the Contributing Guidelines?
Yes
Environment
Environment: OS: macOS Sierra 10.12.6 Node: 7.0.0 npm: 3.10.8 Watchman: 4.7.0 Xcode: 9.1
Packages: (wanted => installed) react-native: 0.49.3 react: 16.0.0-beta.5
Target Platform: iOS (10.3)
Steps to Reproduce
<TextInput>
component withmultiline
prop set.Expected Behavior
Multiline TextInput should scroll above the soft keyboard.
Actual Behavior
Soft keyboard covers multiline TextInput.
Reproducible Demo