React Native Keyboard Covering Inputs

当键盘遮挡住被输入TextInput时,尝试过几种解决思路:

  1. 外侧包一层ScrollView,然后通过ScrollViewscrollTo()来滚到键盘上方,其中的难点在于 怎么计算需要滚动的值,原lego里的Scroll + Input有对应实现,但有bug💔
  2. react nativeKeyboardAvoidingView组件,但在需要用ScrollView的地方很诡异,遂放弃
  3. transform向Y轴平移啊,还不用动TextInput,结合 animation提升用户体验,简直爽得起飞🛫️,😄

20190531更新:1. 实测IOS对动画有一定延时。。 2. 为兼容iPHONE X等全面屏,需对offset单独设置大些的值

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
export default class KeyboardShift extends Component {
state = {
shift: new Animated.Value(0),
};

componentWillMount() {
this.keyboardDidShowSub = Keyboard.addListener('keyboardDidShow', this.handleKeyboardDidShow);
this.keyboardDidHideSub = Keyboard.addListener('keyboardDidHide', this.handleKeyboardDidHide);
}

componentWillUnmount() {
this.keyboardDidShowSub.remove();
this.keyboardDidHideSub.remove();
}

handleKeyboardDidShow = (event) => {
const { height: windowHeight } = Dimensions.get('window');
const keyboardHeight = event.endCoordinates.height;
const currentlyFocusedField = TextInputState.currentlyFocusedField();
UIManager.measure(currentlyFocusedField, (originX, originY, width, height, pageX, pageY) => {
const fieldHeight = height;
const fieldTop = pageY;
const gap = (windowHeight - keyboardHeight) - (fieldTop + fieldHeight) - offset;
if (gap >= 0) {
return;
}
Animated.timing(
this.state.shift,
{
toValue: gap,
duration: 300,
}
).start();
});
}

handleKeyboardDidHide = () => {
Animated.timing(
this.state.shift,
{
toValue: 0,
duration: 300,
}
).start();
}

render() {
const { children, ...other } = this.props;
const { shift } = this.state;
return (
<ScrollView
keyboardShouldPersistTaps="handled"
{...other}
>
<Animated.View style={[styles.container, { transform: [{ translateY: shift }] }]}>
{children}
</Animated.View>
</ScrollView>
);
}
}

KeyboardShift.propTypes = {
children: PropTypes.element.isRequired,
};

ref

© 2019 lvbin's Blog All Rights Reserved.
Theme by hiero