mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Avoid eating clicks/taps into ScrollView when using physical keyboard (#30374)
Summary: This is an extension of https://github.com/facebook/react-native/issues/29798 which was reverted due to cases where the soft keyboard could not be dismissed. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [General] [Fixed] - Avoid eating clicks/taps into ScrollView when using physical keyboard Pull Request resolved: https://github.com/facebook/react-native/pull/30374 Test Plan: Validated with iOS simulator that taps on default ScrollView will dismiss soft keyboard and be eaten if open, but taps are not eaten when emulating a connected physical keyboard. Reviewed By: kacieb Differential Revision: D24935077 Pulled By: lyahdav fbshipit-source-id: 19d9cf64547e40a35f9363896e3abbdccb95b546
This commit is contained in:
committed by
Mike Grabowski
parent
052447c9ac
commit
7ec38b9f44
@@ -186,7 +186,7 @@ const ScrollResponderMixin = {
|
||||
|
||||
if (
|
||||
this.props.keyboardShouldPersistTaps === 'handled' &&
|
||||
currentlyFocusedInput != null &&
|
||||
this.scrollResponderKeyboardIsDismissible() &&
|
||||
e.target !== currentlyFocusedInput
|
||||
) {
|
||||
return true;
|
||||
@@ -223,7 +223,6 @@ const ScrollResponderMixin = {
|
||||
// and a new touch starts with a non-textinput target (in which case the
|
||||
// first tap should be sent to the scroll view and dismiss the keyboard,
|
||||
// then the second tap goes to the actual interior view)
|
||||
const currentlyFocusedTextInput = TextInputState.currentlyFocusedInput();
|
||||
const {keyboardShouldPersistTaps} = this.props;
|
||||
const keyboardNeverPersistTaps =
|
||||
!keyboardShouldPersistTaps || keyboardShouldPersistTaps === 'never';
|
||||
@@ -240,7 +239,7 @@ const ScrollResponderMixin = {
|
||||
|
||||
if (
|
||||
keyboardNeverPersistTaps &&
|
||||
currentlyFocusedTextInput != null &&
|
||||
this.scrollResponderKeyboardIsDismissible() &&
|
||||
e.target != null &&
|
||||
!TextInputState.isTextInput(e.target)
|
||||
) {
|
||||
@@ -250,6 +249,31 @@ const ScrollResponderMixin = {
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Do we consider there to be a dismissible soft-keyboard open?
|
||||
*/
|
||||
scrollResponderKeyboardIsDismissible: function(): boolean {
|
||||
const currentlyFocusedInput = TextInputState.currentlyFocusedInput();
|
||||
|
||||
// We cannot dismiss the keyboard without an input to blur, even if a soft
|
||||
// keyboard is open (e.g. when keyboard is open due to a native component
|
||||
// not participating in TextInputState). It's also possible that the
|
||||
// currently focused input isn't a TextInput (such as by calling ref.focus
|
||||
// on a non-TextInput).
|
||||
const hasFocusedTextInput =
|
||||
currentlyFocusedInput != null &&
|
||||
TextInputState.isTextInput(currentlyFocusedInput);
|
||||
|
||||
// Even if an input is focused, we may not have a keyboard to dismiss. E.g
|
||||
// when using a physical keyboard. Ensure we have an event for an opened
|
||||
// keyboard, except on Android where setting windowSoftInputMode to
|
||||
// adjustNone leads to missing keyboard events.
|
||||
const softKeyboardMayBeOpen =
|
||||
this.keyboardWillOpenTo != null || Platform.OS === 'android';
|
||||
|
||||
return hasFocusedTextInput && softKeyboardMayBeOpen;
|
||||
},
|
||||
|
||||
/**
|
||||
* Invoke this from an `onResponderReject` event.
|
||||
*
|
||||
@@ -324,7 +348,7 @@ const ScrollResponderMixin = {
|
||||
if (
|
||||
this.props.keyboardShouldPersistTaps !== true &&
|
||||
this.props.keyboardShouldPersistTaps !== 'always' &&
|
||||
currentlyFocusedTextInput != null &&
|
||||
this.scrollResponderKeyboardIsDismissible() &&
|
||||
e.target !== currentlyFocusedTextInput &&
|
||||
!this.state.observedScrollSinceBecomingResponder &&
|
||||
!this.state.becameResponderWhileAnimating
|
||||
|
||||
Reference in New Issue
Block a user