-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
117 lines (104 loc) · 4.09 KB
/
main.js
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
const { findNodeHandle, Keyboard, NativeModules, Platform, Dimensions} = require('react-native');
const PAGEH = Dimensions.get('window').height - (Platform.OS == 'ios' ? 0 : 20);
const recoverList = [];
let keyboardSpace = 0;
const updateKeyboardSpace = (event) => {
keyboardSpace = Math.floor(event.endCoordinates.height);
}
const resetFunctions = {
scroll: (item) => {
if ('scrollToOffset' in item.scrollNodeRef) {
item.scrollNodeRef.scrollToOffset({offset: item.contentOffset, animated: true});
} else {
item.scrollNodeRef.scrollTo({x: 0, y: item.contentOffset, animated: true});
}
},
position: (item) => {
item.nodeRef.setNativeProps({
style: {
bottom: item.bottom
}
})
}
}
const resetKeyboardSpace = () => {
keyboardSpace = 0;
recoverList.forEach((item) => {
resetFunctions.hasOwnProperty(item.behavior) && resetFunctions[item.behavior](item);
});
recoverList.length = 0;
}
let keyboardHide, keyboardShow;
let isOn = false;
const initListener = () => {
isOn = true;
if (Platform.OS == 'ios') {
keyboardShow = Keyboard.addListener('keyboardWillShow', updateKeyboardSpace);
keyboardHide = Keyboard.addListener('keyboardWillHide', resetKeyboardSpace);
} else {
keyboardShow = Keyboard.addListener('keyboardDidShow', updateKeyboardSpace);
keyboardHide = Keyboard.addListener('keyboardDidHide', resetKeyboardSpace);
}
}
export default {
unMount: () => {
if (isOn) {
keyboardShow.remove();
keyboardHide.remove();
isOn = false;
}
},
/*
* @param {elements}
* while behavior is scroll {nodeRef, scrollNodeRef, contentOffset},
* while behavior is position {nodeRef},
*
* @param {behavior} string:: scroll,position,padding,height
* @param {targetScrollOffset}
* */
checkNeedScroll: (elements, behavior='scroll', targetScrollOffset=0) => {
!isOn && initListener();
const {nodeRef} = elements;
let handle = findNodeHandle(nodeRef);
NativeModules.UIManager.measure(handle, (x, y, width, height, pageX, pageY) => {
if (behavior == 'scroll') {
let avoidHeight = keyboardSpace + targetScrollOffset;
let offset = avoidHeight - (PAGEH - (pageY + height));
if (offset > 0) {
const {scrollNodeRef, contentOffset} = elements;
recoverList.push({
behavior: behavior,
scrollNodeRef: scrollNodeRef,
paddingBottom: scrollNodeRef.props.style ? scrollNodeRef.props.style.paddingBottom : 0,
contentOffset: contentOffset
});
if ('scrollToOffset' in scrollNodeRef) {
scrollNodeRef.scrollToOffset({offset: offset + contentOffset, animated: true});
} else {
scrollNodeRef.scrollTo({x: 0, y: offset + contentOffset, animated: true});
}
}
} else if (behavior == 'position') {
let bottom = PAGEH - pageY - height;
let avoidHeight = keyboardSpace + bottom;
let offset = avoidHeight - bottom;
if (offset > 0) {
if (nodeRef.setNativeProps) {
recoverList.push({
behavior: behavior,
nodeRef: nodeRef,
bottom: bottom || 0
});
nodeRef.setNativeProps({
style: {
bottom: avoidHeight
}
})
} else {
console.warn('RCTNode type ', nodeRef.viewConfig.uiViewClassName, ' could not used for KeyboardAvoid.');
}
}
}
})
}
}