1717#import < React/RCTUITextField.h>
1818#import < React/RCTUITextView.h>
1919#import < React/RCTUtils.h>
20+ #import < React/UIView+React.h>
21+ #import < React/UIViewController+React.h>
2022
2123#import " RCTConversions.h"
2224#import " RCTTextInputNativeCommands.h"
3234
3335@interface RCTTextInputComponentView () <
3436 RCTBackedTextInputDelegate,
37+ RCTViewControllerAppearanceListener,
3538 RCTTextInputViewProtocol,
3639 UIDropInteractionDelegate>
3740@end
@@ -66,6 +69,8 @@ @implementation RCTTextInputComponentView {
6669 */
6770 BOOL _comingFromJS;
6871 BOOL _didMoveToWindow;
72+ BOOL _didAutoFocus;
73+ __weak UIViewController *_viewController;
6974
7075 /*
7176 * Newly initialized default typing attributes contain a no-op NSParagraphStyle and NSShadow. These cause inequality
@@ -91,6 +96,7 @@ - (instancetype)initWithFrame:(CGRect)frame
9196 _ignoreNextTextInputCall = NO ;
9297 _comingFromJS = NO ;
9398 _didMoveToWindow = NO ;
99+ _didAutoFocus = NO ;
94100 _originalTypingAttributes = [_backedTextInputView.typingAttributes copy ];
95101 _previousContentSize = CGSizeZero;
96102
@@ -117,13 +123,18 @@ - (void)didMoveToWindow
117123{
118124 [super didMoveToWindow ];
119125
126+ bool enableNewAutoFocusImpl = ReactNativeFeatureFlags::enableIOSExperimentalAutoFocusImplementation ();
127+ if (enableNewAutoFocusImpl) {
128+ [_viewController reactRemoveViewControllerAppearanceListener: self ];
129+ _viewController = self.window ? [self reactViewController ] : nil ;
130+ [_viewController reactAddViewControllerAppearanceListener: self ];
131+ }
132+
120133 if (self.window && !_didMoveToWindow) {
121- const auto &props = static_cast <const TextInputProps &>(*_props);
122- if (props.autoFocus ) {
123- [_backedTextInputView becomeFirstResponder ];
124- [self scrollCursorIntoView ];
125- }
126134 _didMoveToWindow = YES ;
135+ if (!enableNewAutoFocusImpl) {
136+ [self tryAutoFocus ];
137+ }
127138 [self initializeReturnKeyType ];
128139 }
129140
@@ -378,9 +389,29 @@ - (void)prepareForRecycle
378389 _lastStringStateWasUpdatedWith = nil ;
379390 _ignoreNextTextInputCall = NO ;
380391 _didMoveToWindow = NO ;
392+ _didAutoFocus = NO ;
393+ [_viewController reactRemoveViewControllerAppearanceListener: self ];
394+ _viewController = nil ;
381395 [_backedTextInputView resignFirstResponder ];
382396}
383397
398+ #pragma mark - Auto focus / RCTViewControllerAppearanceListener
399+
400+ - (void )tryAutoFocus
401+ {
402+ const auto &props = static_cast <const TextInputProps &>(*_props);
403+ if (props.autoFocus && !_didAutoFocus) {
404+ _didAutoFocus = YES ;
405+ [_backedTextInputView becomeFirstResponder ];
406+ [self scrollCursorIntoView ];
407+ }
408+ }
409+
410+ - (void )reactViewControllerDidAppear : (UIViewController *)viewController animated : (BOOL )animated
411+ {
412+ [self tryAutoFocus ];
413+ }
414+
384415#pragma mark - RCTBackedTextInputDelegate
385416
386417- (BOOL )textInputShouldBeginEditing
0 commit comments