From 763f19c1667a57036641fa6d44984d5c26a2a09f Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 18 Jan 2023 15:22:24 +0100 Subject: [PATCH 1/5] Add support for `showSoftInputOnFocus` prop on TextInput iOS --- .../TextInput/RCTTextInputComponentView.mm | 15 +++++++++++++++ .../textinput/iostextinput/TextInputProps.cpp | 6 ++++++ .../textinput/iostextinput/TextInputProps.h | 2 ++ 3 files changed, 23 insertions(+) diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index 156a913c435d6c..517395d676f6c1 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -115,6 +115,10 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & [self _setMultiline:newTextInputProps.traits.multiline]; } + if (newTextInputProps.traits.showSoftInputOnFocus != oldTextInputProps.traits.showSoftInputOnFocus) { + [self _setShowSoftInputOnFocus:newTextInputProps.traits.showSoftInputOnFocus]; + } + if (newTextInputProps.traits.autocapitalizationType != oldTextInputProps.traits.autocapitalizationType) { _backedTextInputView.autocapitalizationType = RCTUITextAutocapitalizationTypeFromAutocapitalizationType(newTextInputProps.traits.autocapitalizationType); @@ -619,6 +623,17 @@ - (void)_setMultiline:(BOOL)multiline [self addSubview:_backedTextInputView]; } +- (void)_setShowSoftInputOnFocus:(BOOL)showSoftInputOnFocus +{ + if (showSoftInputOnFocus) { + // Resets to default keyboard. + _backedTextInputView.inputView = nil; + } else { + // Hides keyboard, but keeps blinking cursor. + _backedTextInputView.inputView = [UIView new]; + } +} + - (BOOL)_textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldText { // When the dictation is running we can't update the attributed text on the backed up text view diff --git a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.cpp b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.cpp index dad0ea7f8ad803..7c64b268b21d34 100644 --- a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.cpp +++ b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.cpp @@ -50,6 +50,12 @@ TextInputProps::TextInputProps( "maxLength", sourceProps.maxLength, {})), + showSoftInputOnFocus(convertRawProp( + context, + rawProps, + "showSoftInputOnFocus", + sourceProps.showSoftInputOnFocus, + {})), cursorColor(convertRawProp( context, rawProps, diff --git a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.h b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.h index bede7451767b36..5f158ae0258ee5 100644 --- a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.h +++ b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputProps.h @@ -49,6 +49,8 @@ class TextInputProps final : public ViewProps, public BaseTextProps { int maxLength{}; + bool showSoftInputOnFocus{true}; + /* * Tint colors */ From 38f6b8121da5ef11f759fd08beb7095149eecc6b Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 18 Jan 2023 15:55:09 +0100 Subject: [PATCH 2/5] Copy implementation --- .../ComponentViews/TextInput/RCTTextInputComponentView.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index 517395d676f6c1..fb8d3576bd2b64 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -628,6 +628,12 @@ - (void)_setShowSoftInputOnFocus:(BOOL)showSoftInputOnFocus if (showSoftInputOnFocus) { // Resets to default keyboard. _backedTextInputView.inputView = nil; + + // Without the call to reloadInputViews, the keyboard will not change until the textInput field (the first + // responder) loses and regains focus. + if (self.backedTextInputView.isFirstResponder) { + [self.backedTextInputView reloadInputViews]; + } } else { // Hides keyboard, but keeps blinking cursor. _backedTextInputView.inputView = [UIView new]; From b68a19eba88242c14cb6a87b5482e118b42060b7 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 18 Jan 2023 16:01:17 +0100 Subject: [PATCH 3/5] Reapply prop when creating new view --- .../ComponentViews/TextInput/RCTTextInputComponentView.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index fb8d3576bd2b64..b81171e7954182 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -621,6 +621,9 @@ - (void)_setMultiline:(BOOL)multiline RCTCopyBackedTextInput(_backedTextInputView, backedTextInputView); _backedTextInputView = backedTextInputView; [self addSubview:_backedTextInputView]; + + auto const ¤tTextInputProps = *std::static_pointer_cast(_props); + [self _setShowSoftInputOnFocus:currentTextInputProps.traits.showSoftInputOnFocus]; } - (void)_setShowSoftInputOnFocus:(BOOL)showSoftInputOnFocus From 05ad3ddb684e1f66f24258a1676060b98f9f3e16 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Wed, 18 Jan 2023 16:19:00 +0100 Subject: [PATCH 4/5] Use correct field --- .../ComponentViews/TextInput/RCTTextInputComponentView.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index b81171e7954182..cffd5de4cae17d 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -634,8 +634,8 @@ - (void)_setShowSoftInputOnFocus:(BOOL)showSoftInputOnFocus // Without the call to reloadInputViews, the keyboard will not change until the textInput field (the first // responder) loses and regains focus. - if (self.backedTextInputView.isFirstResponder) { - [self.backedTextInputView reloadInputViews]; + if (_backedTextInputView.isFirstResponder) { + [_backedTextInputView reloadInputViews]; } } else { // Hides keyboard, but keeps blinking cursor. From f0eadd5bc8128e75e56cb405f6d27d76730b6a42 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Mon, 25 Mar 2024 09:40:37 +0100 Subject: [PATCH 5/5] Move `showSoftInputOnFocus` to base props --- .../renderer/components/textinput/BaseTextInputProps.cpp | 7 +++++++ .../renderer/components/textinput/BaseTextInputProps.h | 2 ++ .../components/androidtextinput/AndroidTextInputProps.cpp | 5 ----- .../components/androidtextinput/AndroidTextInputProps.h | 1 - 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp index 28dc7d87cbdad4..a7728ff8006f92 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp @@ -84,6 +84,12 @@ BaseTextInputProps::BaseTextInputProps( "maxLength", sourceProps.maxLength, {})), + showSoftInputOnFocus(convertRawProp( + context, + rawProps, + "showSoftInputOnFocus", + sourceProps.showSoftInputOnFocus, + {})), text(convertRawProp(context, rawProps, "text", sourceProps.text, {})), mostRecentEventCount(convertRawProp( context, @@ -173,6 +179,7 @@ void BaseTextInputProps::setProp( RAW_SET_PROP_SWITCH_CASE_BASIC(cursorColor); RAW_SET_PROP_SWITCH_CASE_BASIC(text); RAW_SET_PROP_SWITCH_CASE_BASIC(mostRecentEventCount); + RAW_SET_PROP_SWITCH_CASE_BASIC(showSoftInputOnFocus); } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h index c1a3ef1e202e5b..045c39ffac3239 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h @@ -54,6 +54,8 @@ class BaseTextInputProps : public ViewProps, public BaseTextProps { int maxLength{}; + bool showSoftInputOnFocus{false}; + /* * "Private" (only used by TextInput.js) props */ diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp index 38f3474ac350e1..b8804a5ea219fc 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.cpp @@ -71,10 +71,6 @@ AndroidTextInputProps::AndroidTextInputProps( "importantForAutofill", sourceProps.importantForAutofill, {})), - showSoftInputOnFocus(CoreFeatures::enablePropIteratorSetter? sourceProps.showSoftInputOnFocus : convertRawProp(context, rawProps, - "showSoftInputOnFocus", - sourceProps.showSoftInputOnFocus, - {false})), autoCapitalize(CoreFeatures::enablePropIteratorSetter? sourceProps.autoCapitalize : convertRawProp(context, rawProps, "autoCapitalize", sourceProps.autoCapitalize, @@ -227,7 +223,6 @@ void AndroidTextInputProps::setProp( RAW_SET_PROP_SWITCH_CASE_BASIC(inlineImageLeft); RAW_SET_PROP_SWITCH_CASE_BASIC(inlineImagePadding); RAW_SET_PROP_SWITCH_CASE_BASIC(importantForAutofill); - RAW_SET_PROP_SWITCH_CASE_BASIC(showSoftInputOnFocus); RAW_SET_PROP_SWITCH_CASE_BASIC(autoCapitalize); RAW_SET_PROP_SWITCH_CASE_BASIC(autoCorrect); RAW_SET_PROP_SWITCH_CASE_BASIC(allowFontScaling); diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h index 28e5df5976be84..9a3bbb2b436d9a 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h @@ -83,7 +83,6 @@ class AndroidTextInputProps final : public BaseTextInputProps { std::string inlineImageLeft{}; int inlineImagePadding{0}; std::string importantForAutofill{}; - bool showSoftInputOnFocus{false}; std::string autoCapitalize{}; bool autoCorrect{false}; bool allowFontScaling{false};