@@ -4,6 +4,11 @@ import PropTypes from 'prop-types';
4
4
import isEqual from 'lodash.isequal' ;
5
5
import { Picker } from '@react-native-picker/picker' ;
6
6
import { defaultStyles } from './styles' ;
7
+ import { Dimensions } from 'react-native' ;
8
+
9
+ // Measuring the modal before rendering is not working reliably, so we need to hardcode the height
10
+ // This height was tested thoroughly on several iPhone Models (from iPhone 8 to 14 Pro)
11
+ const IOS_MODAL_HEIGHT = 262 ;
7
12
8
13
export default class RNPickerSelect extends PureComponent {
9
14
static propTypes = {
@@ -31,6 +36,8 @@ export default class RNPickerSelect extends PureComponent {
31
36
onOpen : PropTypes . func ,
32
37
useNativeAndroidPickerStyle : PropTypes . bool ,
33
38
fixAndroidTouchableBug : PropTypes . bool ,
39
+ scrollViewRef : PropTypes . any ,
40
+ scrollViewContentOffsetY : PropTypes . number ,
34
41
35
42
// Custom Modal props (iOS only)
36
43
doneText : PropTypes . string ,
@@ -137,6 +144,7 @@ export default class RNPickerSelect extends PureComponent {
137
144
this . onValueChange = this . onValueChange . bind ( this ) ;
138
145
this . onOrientationChange = this . onOrientationChange . bind ( this ) ;
139
146
this . setInputRef = this . setInputRef . bind ( this ) ;
147
+ this . scrollToInput = this . scrollToInput . bind ( this ) ;
140
148
this . togglePicker = this . togglePicker . bind ( this ) ;
141
149
this . renderInputAccessoryView = this . renderInputAccessoryView . bind ( this ) ;
142
150
}
@@ -214,12 +222,37 @@ export default class RNPickerSelect extends PureComponent {
214
222
return { } ;
215
223
}
216
224
225
+ scrollToInput ( ) {
226
+ if (
227
+ this . props . scrollViewRef == null ||
228
+ this . props . scrollViewContentOffsetY == null ||
229
+ this . inputRef == null
230
+ ) {
231
+ return ;
232
+ }
233
+
234
+ this . inputRef . measureInWindow ( ( _x , y , _width , height ) => {
235
+ // Bottom y-position of TextInput on screen
236
+ const textInputBottomY = y + height ;
237
+ // Top y-position of picker modal on screen
238
+ const modalY = Dimensions . get ( 'window' ) . height - IOS_MODAL_HEIGHT ;
239
+
240
+ // If TextInput is below picker modal, scroll up
241
+ if ( textInputBottomY > modalY ) {
242
+ this . props . scrollViewRef . current . scrollTo ( {
243
+ y : textInputBottomY - modalY + this . props . scrollViewContentOffsetY ,
244
+ } ) ;
245
+ }
246
+ } ) ;
247
+ }
248
+
217
249
triggerOpenCloseCallbacks ( ) {
218
250
const { onOpen, onClose } = this . props ;
219
251
const { showPicker } = this . state ;
220
252
221
253
if ( ! showPicker && onOpen ) {
222
254
onOpen ( ) ;
255
+ this . scrollToInput ( ) ;
223
256
}
224
257
225
258
if ( showPicker && onClose ) {
0 commit comments