Reputation: 1796
<View>
<View style = {{height : X}}></View>
<ScrollView>
<KeyboardAvoidingView>
<View style = {{height : 350}}></View>
<TextInput/>
<View style = {{height : 500}}></View>
</KeyboardAvoidingView>
</ScrollView>
</View>
When I tap on the TextInput
, it is scrolled upward but stop at the position of below where it is supposed to be as much as X, which means it is still hidden under the keyboard.
Actually the problem is not about KeyboardAvoidingView because it also happens without the use of it
Upvotes: 1
Views: 7196
Reputation: 1796
render() {
var a = [];
for(var i =1; i< 100; i++) a.push(i);
return (
<View>
<Button title = 'Scroll' onPress = {() => this.refs.scroll.scrollTo({x: 0, y: 0, animated: true})}/>
<ScrollView ref = 'scroll'>{a.map((item, index) => (<TextInput style = {{height : 10 + (Math.floor(Math.random() * 10) * 5)}}
placeholder = {item + ''}
onFocus = {() => {
this.refs.scroll.scrollTo({x : 0, y : this.y[index], animated : true});
}}
onLayout = {event => {
this.y[index] = event.nativeEvent.layout.y;
}}
/>))}</ScrollView>
</View>
);
}
Using this solution, there are 2 drawbacks exist which raise other problems require solutions
TextInput
is inside a FlatList
or perhaps certain components which contain TextInput
indirectly. In this case, event.nativeEvent.layout.y
will always return 0. No problem for multilevel ScrollView
. Temporarily the solution is to avoid placing the TextInput
inside a prop componentTextInput
's offset is relative to wrapper component if it's not the ScrollView
. Scroll distance must be the summation of TextInput
's offset and wrapper's offset if the wrapper is not at the top of ScrollView. Since a parent's post-layout data cannot be passed to a child directly via prop before it is rendered, the TextInput
must get the wrapper's offset in it's onFocus
handleronFocus
, cancelling onFocus
's effect. The temporary solution is to use setTimeout
to delay onFocus
action for at least 200 millisecondsUpvotes: 0
Reputation: 1285
This is what I did it to resolve this issue
<KeyboardAvoiding behavior={'padding'} keyboardVerticalOffset={64} style={styles.container}>
<View style={styles.container}>
<ScrollView keyboardShouldPersistTaps="always">
<View style = {{height : 350}}></View>
<TextInput/>
<View style = {{height : 500}}></View>
</ScrollView>
</View>
</KeyboardAvoiding>
container: {
flex: 1,
alignItems: 'center',
}
and this is the KeyboardAvoiding class
import React from 'react'
import { Platform, KeyboardAvoidingView as ReactNativeKeyboardAvoidingView } from 'react-native'
class KeyboardAvoidingView extends React.Component {
render() {
if (Platform.OS === 'ios') {
return (
<ReactNativeKeyboardAvoidingView behavior={'padding'} {...this.props}>
{this.props.children}
</ReactNativeKeyboardAvoidingView>
)
}
return this.props.children
}
}
KeyboardAvoidingView.propTypes = {
children: React.PropTypes.element,
}
module.exports = KeyboardAvoidingView
Hope this helps.
Upvotes: 4