Skip to content

Commit 552c601

Browse files
janicduplessisFacebook Github Bot
authored andcommitted
Don't dismiss keyboard when tapping another text input
Summary: When using text inputs inside a ScrollView with `keyboardShouldPersistTaps=false` (default behavior) tapping another text input dismisses the keyboard instead of keeping it open and focusing the new text input which I think is the better and expected behavior. See #10628 for more discussion about that. Note that this affects nothing but the behavior with text inputs unlike #10628. cc satya164 MaxLap ericvicenti Closes #10887 Differential Revision: D4178474 Pulled By: ericvicenti fbshipit-source-id: 0c62ea2fac0017d559d1f8674b0a686a5e1b3d2d
1 parent 0e55f5b commit 552c601

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

Libraries/Components/ScrollResponder.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var Subscribable = require('Subscribable');
1919
var TextInputState = require('TextInputState');
2020
var UIManager = require('UIManager');
2121

22+
var { getInstanceFromNode } = require('ReactNativeComponentTree');
2223
var { ScrollViewManager } = require('NativeModules');
2324

2425
var invariant = require('fbjs/lib/invariant');
@@ -112,6 +113,15 @@ type State = {
112113
};
113114
type Event = Object;
114115

116+
function isTagInstanceOfTextInput(tag) {
117+
var instance = getInstanceFromNode(tag);
118+
return instance && instance.viewConfig && (
119+
instance.viewConfig.uiViewClassName === 'AndroidTextInput' ||
120+
instance.viewConfig.uiViewClassName === 'RCTTextView' ||
121+
instance.viewConfig.uiViewClassName === 'RCTTextField'
122+
);
123+
}
124+
115125
var ScrollResponderMixin = {
116126
mixins: [Subscribable.Mixin],
117127
scrollResponderMixinGetInitialState: function(): State {
@@ -172,7 +182,7 @@ var ScrollResponderMixin = {
172182
* that *doesn't* give priority to nested views (hence the capture phase):
173183
*
174184
* - Currently animating.
175-
* - Tapping anywhere that is not the focused input, while the keyboard is
185+
* - Tapping anywhere that is not a text input, while the keyboard is
176186
* up (which should dismiss the keyboard).
177187
*
178188
* Invoke this from an `onStartShouldSetResponderCapture` event.
@@ -182,7 +192,7 @@ var ScrollResponderMixin = {
182192
var currentlyFocusedTextInput = TextInputState.currentlyFocusedField();
183193
if (!this.props.keyboardShouldPersistTaps &&
184194
currentlyFocusedTextInput != null &&
185-
e.target !== currentlyFocusedTextInput) {
195+
!isTagInstanceOfTextInput(e.target)) {
186196
return true;
187197
}
188198
return this.scrollResponderIsAnimating();

Libraries/ReactNative/requireNativeComponent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ function requireNativeComponent(
101101
return createReactNativeComponentClass(viewConfig);
102102
}
103103

104-
var TypeToDifferMap = {
104+
const TypeToDifferMap = {
105105
// iOS Types
106106
CATransform3D: matricesDiffer,
107107
CGPoint: pointsDiffer,
@@ -115,7 +115,7 @@ function processColorArray(colors: []): [] {
115115
return colors && colors.map(processColor);
116116
}
117117

118-
var TypeToProcessorMap = {
118+
const TypeToProcessorMap = {
119119
// iOS Types
120120
CGColor: processColor,
121121
CGColorArray: processColorArray,

ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ private static boolean isTransformedTouchPointInView(
200200
float eventCoords[], View view) {
201201
PointerEvents pointerEvents = view instanceof ReactPointerEventsView ?
202202
((ReactPointerEventsView) view).getPointerEvents() : PointerEvents.AUTO;
203+
204+
// Views that are disabled should never be the target of pointer events. However, their children
205+
// can be because some views (SwipeRefreshLayout) use enabled but still have children that can
206+
// be valid targets.
207+
if (!view.isEnabled()) {
208+
if (pointerEvents == PointerEvents.AUTO) {
209+
pointerEvents = PointerEvents.BOX_NONE;
210+
} else if (pointerEvents == PointerEvents.BOX_ONLY) {
211+
pointerEvents = PointerEvents.NONE;
212+
}
213+
}
214+
203215
if (pointerEvents == PointerEvents.NONE) {
204216
// This view and its children can't be the target
205217
return null;
@@ -209,7 +221,7 @@ private static boolean isTransformedTouchPointInView(
209221
return view;
210222

211223
} else if (pointerEvents == PointerEvents.BOX_NONE) {
212-
// This view can't be the target, but its children might
224+
// This view can't be the target, but its children might.
213225
if (view instanceof ViewGroup) {
214226
View targetView = findTouchTargetView(eventCoords, (ViewGroup) view);
215227
if (targetView != view) {

0 commit comments

Comments
 (0)