mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Do not eat taps/clicks in ScrollView when soft-keyboard is detached from viewport
Summary: If currently focused on a TextInput, clicking an item in a ScrollView takes two clicks. This is because of `keyboardShouldPersistTaps`, which will fire despite a lack of keyboard events on Android due to special-casing. This behavior is jarring in scenarios like VR where the soft keyboard is detached from the application. This change avoids eating taps, in this case, where a soft keyboard is open but not inset. Reviewed By: genkikondo Differential Revision: D38529237 fbshipit-source-id: a10c5dbf04e6288e0e9e0c805215054bc883339f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f5f6896e61
commit
fd1e82a10f
@@ -1510,6 +1510,11 @@ class ScrollView extends React.Component<Props, State> {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let presses through if the soft keyboard is detached from the viewport
|
||||
if (this._softKeyboardIsDetached()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
keyboardNeverPersistTaps &&
|
||||
this._keyboardIsDismissible() &&
|
||||
@@ -1548,6 +1553,15 @@ class ScrollView extends React.Component<Props, State> {
|
||||
return hasFocusedTextInput && softKeyboardMayBeOpen;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether an open soft keyboard is present which does not overlap the
|
||||
* viewport. E.g. for a VR soft-keyboard which is detached from the app
|
||||
* viewport.
|
||||
*/
|
||||
_softKeyboardIsDetached: () => boolean = () => {
|
||||
return this._keyboardMetrics != null && this._keyboardMetrics.height === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoke this from an `onTouchEnd` event.
|
||||
*
|
||||
@@ -1556,6 +1570,21 @@ class ScrollView extends React.Component<Props, State> {
|
||||
_handleTouchEnd: (e: PressEvent) => void = (e: PressEvent) => {
|
||||
const nativeEvent = e.nativeEvent;
|
||||
this._isTouching = nativeEvent.touches.length !== 0;
|
||||
|
||||
const {keyboardShouldPersistTaps} = this.props;
|
||||
const keyboardNeverPersistsTaps =
|
||||
!keyboardShouldPersistTaps || keyboardShouldPersistTaps === 'never';
|
||||
|
||||
// Dismiss the keyboard now if we didn't become responder in capture phase
|
||||
// to eat presses, but still want to dismiss on interaction.
|
||||
if (
|
||||
this._softKeyboardIsDetached() &&
|
||||
this._keyboardIsDismissible() &&
|
||||
keyboardNeverPersistsTaps
|
||||
) {
|
||||
TextInputState.blurTextInput(TextInputState.currentlyFocusedInput());
|
||||
}
|
||||
|
||||
this.props.onTouchEnd && this.props.onTouchEnd(e);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user