From 022e79c5f8cce70d7f4fa32dc0f64f053d2da1f0 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Sat, 18 Jan 2020 01:57:35 -0500 Subject: [PATCH] Implement TextInput autoFocus natively on iOS --- Libraries/Components/TextInput/TextInput.js | 16 ++++++++-------- Libraries/Text/TextInput/RCTBaseTextInputView.h | 1 + Libraries/Text/TextInput/RCTBaseTextInputView.m | 9 ++++++++- .../Text/TextInput/RCTBaseTextInputViewManager.m | 1 + 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 02e1db674aff5e..0f93f4f30e8935 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -698,6 +698,11 @@ function useFocusOnMount( const initialAutoFocusValue = useRef(initialAutoFocus); useEffect(() => { + // On iOS autoFocus is handled natively. + if (Platform.OS === 'ios') { + return; + } + // We only want to autofocus on initial mount. // Since initialAutoFocusValue and inputRef will never change // this should match the expected behavior @@ -708,14 +713,9 @@ function useFocusOnMount( } }; - let rafId; - if (Platform.OS === 'android') { - // On Android this needs to be executed in a rAF callback - // otherwise the keyboard opens then closes immediately. - rafId = requestAnimationFrame(focus); - } else { - focus(); - } + // On Android this needs to be executed in a rAF callback + // otherwise the keyboard opens then closes immediately. + const rafId = requestAnimationFrame(focus); return () => { if (rafId != null) { diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.h b/Libraries/Text/TextInput/RCTBaseTextInputView.h index 186f83d5e80782..99ccfa1e3a01f5 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -40,6 +40,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll; @property (nonatomic, assign) NSInteger mostRecentEventCount; +@property (nonatomic, assign) BOOL autoFocus; @property (nonatomic, assign) BOOL blurOnSubmit; @property (nonatomic, assign) BOOL selectTextOnFocus; @property (nonatomic, assign) BOOL clearTextOnFocus; diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index c61279893f0ad0..e01bd43b67c6e9 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -25,6 +25,7 @@ @implementation RCTBaseTextInputView { BOOL _hasInputAccesoryView; NSString *_Nullable _predictedText; NSInteger _nativeEventCount; + BOOL _didMoveToWindow; } - (instancetype)initWithBridge:(RCTBridge *)bridge @@ -519,7 +520,13 @@ - (void)reactBlur - (void)didMoveToWindow { - [self.backedTextInputView reactFocusIfNeeded]; + if (self.autoFocus && !_didMoveToWindow) { + [self.backedTextInputView reactFocus]; + } else { + [self.backedTextInputView reactFocusIfNeeded]; + } + + _didMoveToWindow = YES; } #pragma mark - Custom Input Accessory View diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 788657c6c8110f..78a61fe9b09af7 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -48,6 +48,7 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL) RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) +RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL) RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL) RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) RCT_EXPORT_VIEW_PROPERTY(keyboardType, UIKeyboardType)