Permalink
Browse files

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
  • Loading branch information...
janicduplessis authored and Facebook Github Bot committed Nov 25, 2016
1 parent 0e55f5b commit 552c60192172f6ec503181c060c08bbc5cbcc5a4
@@ -19,6 +19,7 @@ var Subscribable = require('Subscribable');
var TextInputState = require('TextInputState');
var UIManager = require('UIManager');
var { getInstanceFromNode } = require('ReactNativeComponentTree');
var { ScrollViewManager } = require('NativeModules');
var invariant = require('fbjs/lib/invariant');
@@ -112,6 +113,15 @@ type State = {
};
type Event = Object;
function isTagInstanceOfTextInput(tag) {
var instance = getInstanceFromNode(tag);
return instance && instance.viewConfig && (
instance.viewConfig.uiViewClassName === 'AndroidTextInput' ||
instance.viewConfig.uiViewClassName === 'RCTTextView' ||
instance.viewConfig.uiViewClassName === 'RCTTextField'
);
}
var ScrollResponderMixin = {
mixins: [Subscribable.Mixin],
scrollResponderMixinGetInitialState: function(): State {
@@ -172,7 +182,7 @@ var ScrollResponderMixin = {
* that *doesn't* give priority to nested views (hence the capture phase):
*
* - Currently animating.
* - Tapping anywhere that is not the focused input, while the keyboard is
* - Tapping anywhere that is not a text input, while the keyboard is
* up (which should dismiss the keyboard).
*
* Invoke this from an `onStartShouldSetResponderCapture` event.
@@ -182,7 +192,7 @@ var ScrollResponderMixin = {
var currentlyFocusedTextInput = TextInputState.currentlyFocusedField();
if (!this.props.keyboardShouldPersistTaps &&
currentlyFocusedTextInput != null &&
e.target !== currentlyFocusedTextInput) {
!isTagInstanceOfTextInput(e.target)) {
return true;
}
return this.scrollResponderIsAnimating();
@@ -101,7 +101,7 @@ function requireNativeComponent(
return createReactNativeComponentClass(viewConfig);
}
var TypeToDifferMap = {
const TypeToDifferMap = {
// iOS Types
CATransform3D: matricesDiffer,
CGPoint: pointsDiffer,
@@ -115,7 +115,7 @@ function processColorArray(colors: []): [] {
return colors && colors.map(processColor);
}
var TypeToProcessorMap = {
const TypeToProcessorMap = {
// iOS Types
CGColor: processColor,
CGColorArray: processColorArray,
@@ -200,6 +200,18 @@ private static boolean isTransformedTouchPointInView(
float eventCoords[], View view) {
PointerEvents pointerEvents = view instanceof ReactPointerEventsView ?
((ReactPointerEventsView) view).getPointerEvents() : PointerEvents.AUTO;
// Views that are disabled should never be the target of pointer events. However, their children
// can be because some views (SwipeRefreshLayout) use enabled but still have children that can
// be valid targets.
if (!view.isEnabled()) {
if (pointerEvents == PointerEvents.AUTO) {
pointerEvents = PointerEvents.BOX_NONE;
} else if (pointerEvents == PointerEvents.BOX_ONLY) {
pointerEvents = PointerEvents.NONE;
}
}
if (pointerEvents == PointerEvents.NONE) {
// This view and its children can't be the target
return null;
@@ -209,7 +221,7 @@ private static boolean isTransformedTouchPointInView(
return view;
} else if (pointerEvents == PointerEvents.BOX_NONE) {
// This view can't be the target, but its children might
// This view can't be the target, but its children might.
if (view instanceof ViewGroup) {
View targetView = findTouchTargetView(eventCoords, (ViewGroup) view);
if (targetView != view) {

3 comments on commit 552c601

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Dec 7, 2016

Collaborator

@janicduplessis this only works for android right?

Collaborator

chirag04 replied Dec 7, 2016

@janicduplessis this only works for android right?

@janicduplessis

This comment has been minimized.

Show comment
Hide comment
@janicduplessis

janicduplessis Dec 7, 2016

Collaborator

@chirag04 It works on both, it's just that android required a few additional changes to work.

Collaborator

janicduplessis replied Dec 7, 2016

@chirag04 It works on both, it's just that android required a few additional changes to work.

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Dec 7, 2016

Collaborator

interesting. I did try with this commit and could not get it to work on ios. I will try a repo soon.

Collaborator

chirag04 replied Dec 7, 2016

interesting. I did try with this commit and could not get it to work on ios. I will try a repo soon.

Please sign in to comment.