@@ -4,6 +4,11 @@ import PropTypes from 'prop-types';
44import isEqual from 'lodash.isequal' ;
55import { Picker } from '@react-native-picker/picker' ;
66import { 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 ;
712
813export default class RNPickerSelect extends PureComponent {
914 static propTypes = {
@@ -31,6 +36,8 @@ export default class RNPickerSelect extends PureComponent {
3136 onOpen : PropTypes . func ,
3237 useNativeAndroidPickerStyle : PropTypes . bool ,
3338 fixAndroidTouchableBug : PropTypes . bool ,
39+ scrollViewRef : PropTypes . any ,
40+ scrollViewContentOffsetY : PropTypes . number ,
3441
3542 // Custom Modal props (iOS only)
3643 doneText : PropTypes . string ,
@@ -137,6 +144,7 @@ export default class RNPickerSelect extends PureComponent {
137144 this . onValueChange = this . onValueChange . bind ( this ) ;
138145 this . onOrientationChange = this . onOrientationChange . bind ( this ) ;
139146 this . setInputRef = this . setInputRef . bind ( this ) ;
147+ this . scrollToInput = this . scrollToInput . bind ( this ) ;
140148 this . togglePicker = this . togglePicker . bind ( this ) ;
141149 this . renderInputAccessoryView = this . renderInputAccessoryView . bind ( this ) ;
142150 }
@@ -214,12 +222,37 @@ export default class RNPickerSelect extends PureComponent {
214222 return { } ;
215223 }
216224
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+
217249 triggerOpenCloseCallbacks ( ) {
218250 const { onOpen, onClose } = this . props ;
219251 const { showPicker } = this . state ;
220252
221253 if ( ! showPicker && onOpen ) {
222254 onOpen ( ) ;
255+ this . scrollToInput ( ) ;
223256 }
224257
225258 if ( showPicker && onClose ) {
0 commit comments