Skip to content

Commit ca4ee56

Browse files
hknaknmeta-codesync[bot]
authored andcommitted
fix(iOS): gate canBecomeFirstResponder behind enableImperativeFocus flag (#56366)
Summary: Fixes a critical iOS regression introduced in RN 0.83 (#53825) where `RCTViewComponentView.canBecomeFirstResponder` unconditionally returns `YES`. This causes UIKit to promote parent views to first responder via `_promoteSelfOrDescendantToFirstResponderIfNecessary`, resulting in: 1. **TextInput autoFocus regression** — inputs lose focus on mount (focus→blur cycle) 2. **Keyboard reopening** — after any TextInput was focused/dismissed, opening native overlays (UIMenu, dropdown menus, header toolbar buttons) causes the keyboard to reappear unexpectedly ### Root Cause PR #53825 added `canBecomeFirstResponder: YES` as part of the `enableImperativeFocus` feature, but didn't gate the return value behind the feature flag. When the flag is `false` (default), every `RCTViewComponentView` still claims first responder eligibility, causing UIKit's `_promoteSelfOrDescendantToFirstResponderIfNecessary` to steal focus from TextInputs. Two distinct failure modes: 1. **On navigation transitions** — UIKit calls `_promoteSelfOrDescendantToFirstResponderIfNecessary` on the incoming screen's root view, walks the hierarchy, finds an `RCTViewComponentView` that returns `YES`, and promotes it — stealing focus from a TextInput that just called `becomeFirstResponder`. 2. **On native overlay dismissal** — When UIMenu/context menu/toolbar dismisses, UIKit restores first responder by walking to the nearest view claiming first responder eligibility, which is now every `RCTViewComponentView`. ### Fix Gate `canBecomeFirstResponder` behind the `enableImperativeFocus` feature flag. When `false` (the default for all existing apps), views don't claim first responder — fixing the regression. When `true`, the imperative focus/blur feature works as designed. This change is safe: `enableImperativeFocus` defaults to `false`, so the gated path only activates for apps explicitly opting in to the new focus/blur commands. Credit to war-in for identifying this fix in #55908. Fixes #55116 Related: expo/expo#43198, software-mansion/react-native-screens#3763, software-mansion/react-native-screens#3677 ## Changelog:[iOS] [Fixed] - Gate RCTViewComponentView.canBecomeFirstResponder behind enableImperativeFocus flag to prevent keyboard reopening and focus theft in Fabric apps Pull Request resolved: #56366 Test Plan: 1. Create a screen with a `TextInput` that has `autoFocus={true}` 2. Navigate to that screen using React Navigation (Stack) 3. Verify `TextInput` retains focus and keyboard stays visible — previously it would focus then immediately blur 4. Dismiss the keyboard, then open a native UIMenu or press a toolbar button 5. Verify keyboard does **NOT** reopen 6. Enable `enableImperativeFocus` flag, verify `focus()`/`blur()` commands still work on Views > **Note:** This PR is intended as a backup to #55908 by war-in, which has the identical fix. If that PR gets reviewed and merged, this can be closed. Opening this to increase visibility on a critical regression affecting all RN 0.83+ iOS Fabric apps. Reviewed By: cipolleschi Differential Revision: D99994820 Pulled By: javache fbshipit-source-id: bdfea2b01e43afa05e8cf35d12d9ccf7a56d63ca
1 parent b1d12f5 commit ca4ee56

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1721,7 +1721,7 @@ - (void)transferVisualPropertiesFromView:(UIView *)sourceView toView:(UIView *)d
17211721

17221722
- (BOOL)canBecomeFirstResponder
17231723
{
1724-
return YES;
1724+
return ReactNativeFeatureFlags::enableImperativeFocus();
17251725
}
17261726

17271727
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args

0 commit comments

Comments
 (0)