Skip to content

Commit 408d308

Browse files
NickGerlemanalloy
andauthored
[0.63] Avoid eating clicks/taps into ScrollView when using physical keyboard… (#668)
* Avoid eating clicks/taps into ScrollView when using physical keyboard (facebook#30374) Summary: This is an extension of facebook#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: facebook#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 * [ado] Workaround homebrew openssl issue actions/runner-images#1811 (comment) * [RNTester] Update pods Co-authored-by: Eloy Durán <eloy.de.enige@gmail.com>
1 parent 2794a7e commit 408d308

File tree

3 files changed

+267
-240
lines changed

3 files changed

+267
-240
lines changed

.ado/templates/apple-node-setup.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# Task Group: Brew install node version
33
#
44
steps:
5+
- script: 'brew uninstall openssl@1.0.2t && rm -rf /usr/local/etc/openssl && rm -rf /usr/local/etc/openssl@1.1'
6+
displayName: Fix Homebrew
7+
58
- script: 'brew bundle'
69
displayName: 'brew bundle'
710

Libraries/Components/ScrollResponder.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ const ScrollResponderMixin = {
187187

188188
if (
189189
this.props.keyboardShouldPersistTaps === 'handled' &&
190-
currentlyFocusedInput != null &&
190+
this.scrollResponderKeyboardIsDismissible() &&
191191
e.target !== currentlyFocusedInput
192192
) {
193193
return true;
@@ -224,7 +224,6 @@ const ScrollResponderMixin = {
224224
// and a new touch starts with a non-textinput target (in which case the
225225
// first tap should be sent to the scroll view and dismiss the keyboard,
226226
// then the second tap goes to the actual interior view)
227-
const currentlyFocusedTextInput = TextInputState.currentlyFocusedInput();
228227
const {keyboardShouldPersistTaps} = this.props;
229228
const keyboardNeverPersistTaps =
230229
!keyboardShouldPersistTaps || keyboardShouldPersistTaps === 'never';
@@ -241,7 +240,7 @@ const ScrollResponderMixin = {
241240

242241
if (
243242
keyboardNeverPersistTaps &&
244-
currentlyFocusedTextInput != null &&
243+
this.scrollResponderKeyboardIsDismissible() &&
245244
e.target != null &&
246245
!TextInputState.isTextInput(e.target)
247246
) {
@@ -251,6 +250,31 @@ const ScrollResponderMixin = {
251250
return false;
252251
},
253252

253+
/**
254+
* Do we consider there to be a dismissible soft-keyboard open?
255+
*/
256+
scrollResponderKeyboardIsDismissible: function(): boolean {
257+
const currentlyFocusedInput = TextInputState.currentlyFocusedInput();
258+
259+
// We cannot dismiss the keyboard without an input to blur, even if a soft
260+
// keyboard is open (e.g. when keyboard is open due to a native component
261+
// not participating in TextInputState). It's also possible that the
262+
// currently focused input isn't a TextInput (such as by calling ref.focus
263+
// on a non-TextInput).
264+
const hasFocusedTextInput =
265+
currentlyFocusedInput != null &&
266+
TextInputState.isTextInput(currentlyFocusedInput);
267+
268+
// Even if an input is focused, we may not have a keyboard to dismiss. E.g
269+
// when using a physical keyboard. Ensure we have an event for an opened
270+
// keyboard, except on Android where setting windowSoftInputMode to
271+
// adjustNone leads to missing keyboard events.
272+
const softKeyboardMayBeOpen =
273+
this.keyboardWillOpenTo != null || Platform.OS === 'android';
274+
275+
return hasFocusedTextInput && softKeyboardMayBeOpen;
276+
},
277+
254278
/**
255279
* Invoke this from an `onResponderReject` event.
256280
*
@@ -325,7 +349,7 @@ const ScrollResponderMixin = {
325349
if (
326350
this.props.keyboardShouldPersistTaps !== true &&
327351
this.props.keyboardShouldPersistTaps !== 'always' &&
328-
currentlyFocusedTextInput != null &&
352+
this.scrollResponderKeyboardIsDismissible() &&
329353
e.target !== currentlyFocusedTextInput &&
330354
!this.state.observedScrollSinceBecomingResponder &&
331355
!this.state.becameResponderWhileAnimating

0 commit comments

Comments
 (0)