diff --git a/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm index 725c37baf52b..9ef4f13a88ad 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm @@ -7,6 +7,7 @@ #import "RCTDefaultReactNativeFactoryDelegate.h" #import +#import #import "RCTAppSetupUtils.h" #import "RCTDependencyProvider.h" #if USE_THIRD_PARTY_JSC != 1 @@ -28,7 +29,7 @@ - (NSURL *_Nullable)sourceURLForBridge:(nonnull RCTBridge *)bridge - (UIViewController *)createRootViewController { - return [UIViewController new]; + return [RCTViewController new]; } - (RCTBridge *)createBridgeWithDelegate:(id)delegate launchOptions:(NSDictionary *)launchOptions diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index c0e56acd2a0f..cf783ed512aa 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -17,6 +17,8 @@ #import #import #import +#import +#import #import "RCTConversions.h" #import "RCTTextInputNativeCommands.h" @@ -32,6 +34,7 @@ @interface RCTTextInputComponentView () < RCTBackedTextInputDelegate, + RCTViewControllerAppearanceListener, RCTTextInputViewProtocol #if !TARGET_OS_TV , @@ -70,6 +73,8 @@ @implementation RCTTextInputComponentView { */ BOOL _comingFromJS; BOOL _didMoveToWindow; + BOOL _didAutoFocus; + __weak UIViewController *_viewController; /* * Newly initialized default typing attributes contain a no-op NSParagraphStyle and NSShadow. These cause inequality @@ -95,6 +100,7 @@ - (instancetype)initWithFrame:(CGRect)frame _ignoreNextTextInputCall = NO; _comingFromJS = NO; _didMoveToWindow = NO; + _didAutoFocus = NO; _originalTypingAttributes = [_backedTextInputView.typingAttributes copy]; _previousContentSize = CGSizeZero; @@ -121,13 +127,18 @@ - (void)didMoveToWindow { [super didMoveToWindow]; + bool enableNewAutoFocusImpl = ReactNativeFeatureFlags::enableIOSExperimentalAutoFocusImplementation(); + if (enableNewAutoFocusImpl) { + [_viewController reactRemoveViewControllerAppearanceListener:self]; + _viewController = self.window ? [self reactViewController] : nil; + [_viewController reactAddViewControllerAppearanceListener:self]; + } + if (self.window && !_didMoveToWindow) { - const auto &props = static_cast(*_props); - if (props.autoFocus) { - [_backedTextInputView becomeFirstResponder]; - [self scrollCursorIntoView]; - } _didMoveToWindow = YES; + if (!enableNewAutoFocusImpl) { + [self tryAutoFocus]; + } [self initializeReturnKeyType]; } @@ -384,12 +395,32 @@ - (void)prepareForRecycle _lastStringStateWasUpdatedWith = nil; _ignoreNextTextInputCall = NO; _didMoveToWindow = NO; + _didAutoFocus = NO; + [_viewController reactRemoveViewControllerAppearanceListener:self]; + _viewController = nil; _backedTextInputView.inputAccessoryViewID = nil; _backedTextInputView.inputAccessoryView = nil; _hasInputAccessoryView = false; [_backedTextInputView resignFirstResponder]; } +#pragma mark - Auto focus / RCTViewControllerAppearanceListener + +- (void)tryAutoFocus +{ + const auto &props = static_cast(*_props); + if (props.autoFocus && !_didAutoFocus) { + _didAutoFocus = YES; + [_backedTextInputView becomeFirstResponder]; + [self scrollCursorIntoView]; + } +} + +- (void)reactViewControllerDidAppear:(UIViewController *)viewController animated:(BOOL)animated +{ + [self tryAutoFocus]; +} + #pragma mark - RCTBackedTextInputDelegate - (BOOL)textInputShouldBeginEditing diff --git a/packages/react-native/React/Views/RCTViewController.h b/packages/react-native/React/Views/RCTViewController.h new file mode 100644 index 000000000000..020630862dec --- /dev/null +++ b/packages/react-native/React/Views/RCTViewController.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RCTViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/react-native/React/Views/RCTViewController.m b/packages/react-native/React/Views/RCTViewController.m new file mode 100644 index 000000000000..c9d111b3e17a --- /dev/null +++ b/packages/react-native/React/Views/RCTViewController.m @@ -0,0 +1,29 @@ +// +// RCTViewController.m +// React-Core +// +// Created by Hanno Goedecke on 27.04.26. +// + +#import "RCTViewController.h" +#import + +@interface RCTViewController () + +@end + +@implementation RCTViewController + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + [self reactNotifyViewControllerDidAppear:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + [self reactNotifyViewControllerDidDisappear:animated]; +} + +@end diff --git a/packages/react-native/React/Views/RCTWrapperViewController.h b/packages/react-native/React/Views/RCTWrapperViewController.h index b8277587684b..08100afb0d58 100644 --- a/packages/react-native/React/Views/RCTWrapperViewController.h +++ b/packages/react-native/React/Views/RCTWrapperViewController.h @@ -5,11 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -#import +#import @class RCTWrapperViewController; -@interface RCTWrapperViewController : UIViewController +@interface RCTWrapperViewController : RCTViewController - (instancetype)initWithContentView:(UIView *)contentView NS_DESIGNATED_INITIALIZER; diff --git a/packages/react-native/React/Views/UIViewController+React.h b/packages/react-native/React/Views/UIViewController+React.h new file mode 100644 index 000000000000..f765467a0223 --- /dev/null +++ b/packages/react-native/React/Views/UIViewController+React.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol RCTViewControllerAppearanceListener + +@optional +- (void)reactViewControllerDidAppear:(UIViewController *)viewController animated:(BOOL)animated; +- (void)reactViewControllerDidDisappear:(UIViewController *)viewController animated:(BOOL)animated; + +@end + +@interface UIViewController (React) + +@property (nonatomic, assign, readonly) BOOL reactViewControllerIsVisible; + +- (void)reactAddViewControllerAppearanceListener:(id)listener; +- (void)reactRemoveViewControllerAppearanceListener:(id)listener; + +/** + * Call from `viewDidAppear:` / `viewDidDisappear:` in UIViewController subclasses + * that want to notify registered React Native appearance listeners. + */ +- (void)reactNotifyViewControllerDidAppear:(BOOL)animated; +- (void)reactNotifyViewControllerDidDisappear:(BOOL)animated; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/react-native/React/Views/UIViewController+React.m b/packages/react-native/React/Views/UIViewController+React.m new file mode 100644 index 000000000000..df18a0904051 --- /dev/null +++ b/packages/react-native/React/Views/UIViewController+React.m @@ -0,0 +1,89 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "UIViewController+React.h" + +#import + +@interface RCTViewControllerAppearanceState : NSObject + +@property (nonatomic, strong, readonly) NSHashTable> *listeners; +@property (nonatomic, assign) BOOL visible; + +@end + +@implementation RCTViewControllerAppearanceState + +- (instancetype)init +{ + if (self = [super init]) { + _listeners = [NSHashTable weakObjectsHashTable]; + } + return self; +} + +@end + +@implementation UIViewController (React) + +- (RCTViewControllerAppearanceState *)reactViewControllerAppearanceState +{ + RCTViewControllerAppearanceState *state = + objc_getAssociatedObject(self, @selector(reactViewControllerAppearanceState)); + if (!state) { + state = [RCTViewControllerAppearanceState new]; + objc_setAssociatedObject( + self, @selector(reactViewControllerAppearanceState), state, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return state; +} + +- (BOOL)reactViewControllerIsVisible +{ + return [self reactViewControllerAppearanceState].visible; +} + +- (void)reactAddViewControllerAppearanceListener:(id)listener +{ + RCTViewControllerAppearanceState *state = [self reactViewControllerAppearanceState]; + [state.listeners addObject:listener]; + + if (state.visible && [listener respondsToSelector:@selector(reactViewControllerDidAppear:animated:)]) { + [listener reactViewControllerDidAppear:self animated:NO]; + } +} + +- (void)reactRemoveViewControllerAppearanceListener:(id)listener +{ + [[self reactViewControllerAppearanceState].listeners removeObject:listener]; +} + +- (void)reactNotifyViewControllerDidAppear:(BOOL)animated +{ + RCTViewControllerAppearanceState *state = [self reactViewControllerAppearanceState]; + state.visible = YES; + + for (id listener in state.listeners.allObjects) { + if ([listener respondsToSelector:@selector(reactViewControllerDidAppear:animated:)]) { + [listener reactViewControllerDidAppear:self animated:animated]; + } + } +} + +- (void)reactNotifyViewControllerDidDisappear:(BOOL)animated +{ + RCTViewControllerAppearanceState *state = [self reactViewControllerAppearanceState]; + state.visible = NO; + + for (id listener in state.listeners.allObjects) { + if ([listener respondsToSelector:@selector(reactViewControllerDidDisappear:animated:)]) { + [listener reactViewControllerDidDisappear:self animated:animated]; + } + } +} + +@end diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 5a9736feef95..382061a5b911 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<1e2cf81bf4354a7e3d9d09384d813cfc>> */ /** @@ -186,6 +186,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableFontScaleChangesUpdatingLayout(): Boolean = accessor.enableFontScaleChangesUpdatingLayout() + /** + * Fixes #56595 by moving the autoFocus from didMoveToWindow to viewDidAppear + */ + @JvmStatic + public fun enableIOSExperimentalAutoFocusImplementation(): Boolean = accessor.enableIOSExperimentalAutoFocusImplementation() + /** * Applies base offset for each line of text separately on iOS. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 31e7ff51beb2..9937b497fd28 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<8dd2a1c47c059810961eb66b13b18dc1>> */ /** @@ -46,6 +46,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererCache: Boolean? = null private var enableFontScaleChangesUpdatingLayoutCache: Boolean? = null + private var enableIOSExperimentalAutoFocusImplementationCache: Boolean? = null private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableImagePrefetchingAndroidCache: Boolean? = null @@ -346,6 +347,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableIOSExperimentalAutoFocusImplementation(): Boolean { + var cached = enableIOSExperimentalAutoFocusImplementationCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableIOSExperimentalAutoFocusImplementation() + enableIOSExperimentalAutoFocusImplementationCache = cached + } + return cached + } + override fun enableIOSTextBaselineOffsetPerLine(): Boolean { var cached = enableIOSTextBaselineOffsetPerLineCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 345b7649dfde..681a654f85cb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<62d1f0fcdf8e3165480da12575d62826>> + * @generated SignedSource<> */ /** @@ -80,6 +80,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableFontScaleChangesUpdatingLayout(): Boolean + @DoNotStrip @JvmStatic public external fun enableIOSExperimentalAutoFocusImplementation(): Boolean + @DoNotStrip @JvmStatic public external fun enableIOSTextBaselineOffsetPerLine(): Boolean @DoNotStrip @JvmStatic public external fun enableIOSViewClipToPaddingBox(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index e9d57e7423b3..3b24f9b18796 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<84ac5b80585f9185c879c81822718d86>> + * @generated SignedSource<<27361d399f26a6f7462a82f9fbfd5d48>> */ /** @@ -75,6 +75,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableFontScaleChangesUpdatingLayout(): Boolean = true + override fun enableIOSExperimentalAutoFocusImplementation(): Boolean = false + override fun enableIOSTextBaselineOffsetPerLine(): Boolean = false override fun enableIOSViewClipToPaddingBox(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index d076ea34d2ff..ae4992cbb293 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3574e23fe8f846e408964af26cf0dd4c>> + * @generated SignedSource<> */ /** @@ -50,6 +50,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererCache: Boolean? = null private var enableFontScaleChangesUpdatingLayoutCache: Boolean? = null + private var enableIOSExperimentalAutoFocusImplementationCache: Boolean? = null private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null private var enableImagePrefetchingAndroidCache: Boolean? = null @@ -376,6 +377,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableIOSExperimentalAutoFocusImplementation(): Boolean { + var cached = enableIOSExperimentalAutoFocusImplementationCache + if (cached == null) { + cached = currentProvider.enableIOSExperimentalAutoFocusImplementation() + accessedFeatureFlags.add("enableIOSExperimentalAutoFocusImplementation") + enableIOSExperimentalAutoFocusImplementationCache = cached + } + return cached + } + override fun enableIOSTextBaselineOffsetPerLine(): Boolean { var cached = enableIOSTextBaselineOffsetPerLineCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt index c806054c45fc..3bad62e6b8b1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<187ac62197545fbce9d537527b4aed3b>> + * @generated SignedSource<> */ /** @@ -27,6 +27,8 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android : override fun enableAccessibilityOrder(): Boolean = true + override fun enableIOSExperimentalAutoFocusImplementation(): Boolean = true + override fun enableSwiftUIBasedFilters(): Boolean = true override fun preventShadowTreeCommitExhaustion(): Boolean = true diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 6edb264c3c99..1bb0103414b5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<9222fd90d191a91893e2c58770d83259>> + * @generated SignedSource<> */ /** @@ -75,6 +75,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableFontScaleChangesUpdatingLayout(): Boolean + @DoNotStrip public fun enableIOSExperimentalAutoFocusImplementation(): Boolean + @DoNotStrip public fun enableIOSTextBaselineOffsetPerLine(): Boolean @DoNotStrip public fun enableIOSViewClipToPaddingBox(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 365b7f6392a0..777f34dcbee7 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -195,6 +195,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableIOSExperimentalAutoFocusImplementation() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableIOSExperimentalAutoFocusImplementation"); + return method(javaProvider_); + } + bool enableIOSTextBaselineOffsetPerLine() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableIOSTextBaselineOffsetPerLine"); @@ -719,6 +725,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableFontScaleChangesUpdatingLayout( return ReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout(); } +bool JReactNativeFeatureFlagsCxxInterop::enableIOSExperimentalAutoFocusImplementation( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableIOSExperimentalAutoFocusImplementation(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableIOSTextBaselineOffsetPerLine( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableIOSTextBaselineOffsetPerLine(); @@ -1153,6 +1164,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableFontScaleChangesUpdatingLayout", JReactNativeFeatureFlagsCxxInterop::enableFontScaleChangesUpdatingLayout), + makeNativeMethod( + "enableIOSExperimentalAutoFocusImplementation", + JReactNativeFeatureFlagsCxxInterop::enableIOSExperimentalAutoFocusImplementation), makeNativeMethod( "enableIOSTextBaselineOffsetPerLine", JReactNativeFeatureFlagsCxxInterop::enableIOSTextBaselineOffsetPerLine), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 27d515ea5167..0c1b2830c9d6 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<773741594e911047dac28904e9fc9544>> + * @generated SignedSource<<0d42119f721e3240e5d140b865547e18>> */ /** @@ -108,6 +108,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableFontScaleChangesUpdatingLayout( facebook::jni::alias_ref); + static bool enableIOSExperimentalAutoFocusImplementation( + facebook::jni::alias_ref); + static bool enableIOSTextBaselineOffsetPerLine( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 071660787b0b..2d35115ccdce 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6a15a6444767342acf4da0c0c8aa6208>> + * @generated SignedSource<<11c0b22fb3739bdbb269084214263fe3>> */ /** @@ -130,6 +130,10 @@ bool ReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout() { return getAccessor().enableFontScaleChangesUpdatingLayout(); } +bool ReactNativeFeatureFlags::enableIOSExperimentalAutoFocusImplementation() { + return getAccessor().enableIOSExperimentalAutoFocusImplementation(); +} + bool ReactNativeFeatureFlags::enableIOSTextBaselineOffsetPerLine() { return getAccessor().enableIOSTextBaselineOffsetPerLine(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index dab48f3e43cc..37994150284d 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<62d1840f9a39eaceaa800542b7351a41>> + * @generated SignedSource<<48115b5bbcdf8122a252d6c6c16e9c81>> */ /** @@ -169,6 +169,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableFontScaleChangesUpdatingLayout(); + /** + * Fixes #56595 by moving the autoFocus from didMoveToWindow to viewDidAppear + */ + RN_EXPORT static bool enableIOSExperimentalAutoFocusImplementation(); + /** * Applies base offset for each line of text separately on iOS. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index d4f6761af0e7..e99a424a8d53 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -497,6 +497,24 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableIOSExperimentalAutoFocusImplementation() { + auto flagValue = enableIOSExperimentalAutoFocusImplementation_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(26, "enableIOSExperimentalAutoFocusImplementation"); + + flagValue = currentProvider_->enableIOSExperimentalAutoFocusImplementation(); + enableIOSExperimentalAutoFocusImplementation_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { auto flagValue = enableIOSTextBaselineOffsetPerLine_.load(); @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(27, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(28, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(29, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingJNIBatchingAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableImagePrefetchingJNIBatchingAndroid"); + markFlagAsAccessed(30, "enableImagePrefetchingJNIBatchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingJNIBatchingAndroid(); enableImagePrefetchingJNIBatchingAndroid_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingOnUiThreadAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableImagePrefetchingOnUiThreadAndroid"); + markFlagAsAccessed(31, "enableImagePrefetchingOnUiThreadAndroid"); flagValue = currentProvider_->enableImagePrefetchingOnUiThreadAndroid(); enableImagePrefetchingOnUiThreadAndroid_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(32, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableImperativeFocus"); + markFlagAsAccessed(33, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(34, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(35, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableKeyEvents"); + markFlagAsAccessed(36, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(37, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(38, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueCoordinatorOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(39, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(40, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMutationObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableMutationObserverByDefault"); + markFlagAsAccessed(41, "enableMutationObserverByDefault"); flagValue = currentProvider_->enableMutationObserverByDefault(); enableMutationObserverByDefault_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableNativeCSSParsing"); + markFlagAsAccessed(42, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeViewPropTransformations() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableNativeViewPropTransformations"); + markFlagAsAccessed(43, "enableNativeViewPropTransformations"); flagValue = currentProvider_->enableNativeViewPropTransformations(); enableNativeViewPropTransformations_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enableNetworkEventReporting"); + markFlagAsAccessed(44, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enablePreparedTextLayout"); + markFlagAsAccessed(45, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(46, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(47, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableViewCulling"); + markFlagAsAccessed(48, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "enableViewRecycling"); + markFlagAsAccessed(49, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "enableViewRecyclingForImage"); + markFlagAsAccessed(50, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(51, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "enableViewRecyclingForText"); + markFlagAsAccessed(52, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "enableViewRecyclingForView"); + markFlagAsAccessed(53, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(54, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(55, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorParentTagForUnflattenCase // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "fixDifferentiatorParentTagForUnflattenCase"); + markFlagAsAccessed(56, "fixDifferentiatorParentTagForUnflattenCase"); flagValue = currentProvider_->fixDifferentiatorParentTagForUnflattenCase(); fixDifferentiatorParentTagForUnflattenCase_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::fixFindShadowNodeByTagRaceCondition() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "fixFindShadowNodeByTagRaceCondition"); + markFlagAsAccessed(57, "fixFindShadowNodeByTagRaceCondition"); flagValue = currentProvider_->fixFindShadowNodeByTagRaceCondition(); fixFindShadowNodeByTagRaceCondition_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(58, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::fixYogaFlexBasisFitContentInMainAxis() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "fixYogaFlexBasisFitContentInMainAxis"); + markFlagAsAccessed(59, "fixYogaFlexBasisFitContentInMainAxis"); flagValue = currentProvider_->fixYogaFlexBasisFitContentInMainAxis(); fixYogaFlexBasisFitContentInMainAxis_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(60, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "fuseboxEnabledRelease"); + markFlagAsAccessed(61, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxFrameRecordingEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "fuseboxFrameRecordingEnabled"); + markFlagAsAccessed(62, "fuseboxFrameRecordingEnabled"); flagValue = currentProvider_->fuseboxFrameRecordingEnabled(); fuseboxFrameRecordingEnabled_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(63, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "fuseboxScreenshotCaptureEnabled"); + markFlagAsAccessed(64, "fuseboxScreenshotCaptureEnabled"); flagValue = currentProvider_->fuseboxScreenshotCaptureEnabled(); fuseboxScreenshotCaptureEnabled_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(65, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(66, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1226,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "perfIssuesEnabled"); + markFlagAsAccessed(67, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "perfMonitorV2Enabled"); + markFlagAsAccessed(68, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1262,7 +1280,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "preparedTextCacheSize"); + markFlagAsAccessed(69, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(70, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1298,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "redBoxV2Android"); + markFlagAsAccessed(71, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "redBoxV2IOS"); + markFlagAsAccessed(72, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(73, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1352,7 +1370,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(74, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1370,7 +1388,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(75, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1388,7 +1406,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(76, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1406,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(77, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1424,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(78, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1442,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(79, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1460,7 +1478,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "useFabricInterop"); + markFlagAsAccessed(80, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1478,7 +1496,7 @@ bool ReactNativeFeatureFlagsAccessor::useLISAlgorithmInDifferentiator() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "useLISAlgorithmInDifferentiator"); + markFlagAsAccessed(81, "useLISAlgorithmInDifferentiator"); flagValue = currentProvider_->useLISAlgorithmInDifferentiator(); useLISAlgorithmInDifferentiator_ = flagValue; @@ -1496,7 +1514,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(82, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1514,7 +1532,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "useNestedScrollViewAndroid"); + markFlagAsAccessed(83, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1532,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "useSharedAnimatedBackend"); + markFlagAsAccessed(84, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1550,7 +1568,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(85, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1568,7 +1586,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(85, "useTurboModuleInterop"); + markFlagAsAccessed(86, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1586,7 +1604,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(86, "useTurboModules"); + markFlagAsAccessed(87, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1604,7 +1622,7 @@ bool ReactNativeFeatureFlagsAccessor::useUnorderedMapInDifferentiator() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(87, "useUnorderedMapInDifferentiator"); + markFlagAsAccessed(88, "useUnorderedMapInDifferentiator"); flagValue = currentProvider_->useUnorderedMapInDifferentiator(); useUnorderedMapInDifferentiator_ = flagValue; @@ -1622,7 +1640,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(88, "viewCullingOutsetRatio"); + markFlagAsAccessed(89, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1640,7 +1658,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(89, "viewTransitionEnabled"); + markFlagAsAccessed(90, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1658,7 +1676,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(90, "virtualViewPrerenderRatio"); + markFlagAsAccessed(91, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 9529d8a54065..7a36e0e31351 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<11a1936e637ed40b79a1aedd02932e7b>> + * @generated SignedSource<<2cc8cebd572ffe79f7ffc7e312d7eb13>> */ /** @@ -58,6 +58,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableFabricLogs(); bool enableFabricRenderer(); bool enableFontScaleChangesUpdatingLayout(); + bool enableIOSExperimentalAutoFocusImplementation(); bool enableIOSTextBaselineOffsetPerLine(); bool enableIOSViewClipToPaddingBox(); bool enableImagePrefetchingAndroid(); @@ -134,7 +135,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 91> accessedFeatureFlags_; + std::array, 92> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -162,6 +163,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableFabricLogs_; std::atomic> enableFabricRenderer_; std::atomic> enableFontScaleChangesUpdatingLayout_; + std::atomic> enableIOSExperimentalAutoFocusImplementation_; std::atomic> enableIOSTextBaselineOffsetPerLine_; std::atomic> enableIOSViewClipToPaddingBox_; std::atomic> enableImagePrefetchingAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index e37c310a2b4b..d59c43015fb3 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6aa42056b9acfeb38e3ea612b6421a15>> + * @generated SignedSource<<9409d4088a4d1b7b454af0df9816fc58>> */ /** @@ -131,6 +131,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return true; } + bool enableIOSExperimentalAutoFocusImplementation() override { + return false; + } + bool enableIOSTextBaselineOffsetPerLine() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 5269d2c64c88..3e20b2284f13 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2a4b0d699f7e7e701defd972cd79b116>> + * @generated SignedSource<<27db9899bab6acfdc4e674d4ca4a0f0a>> */ /** @@ -279,6 +279,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableFontScaleChangesUpdatingLayout(); } + bool enableIOSExperimentalAutoFocusImplementation() override { + auto value = values_["enableIOSExperimentalAutoFocusImplementation"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableIOSExperimentalAutoFocusImplementation(); + } + bool enableIOSTextBaselineOffsetPerLine() override { auto value = values_["enableIOSTextBaselineOffsetPerLine"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h index e84785c6fd2c..45d1c43d2888 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<577f69448b914525ff64e851c6019c1f>> */ /** @@ -35,6 +35,10 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur return true; } + bool enableIOSExperimentalAutoFocusImplementation() override { + return true; + } + bool enableSwiftUIBasedFilters() override { return true; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 9eef5b56f5e9..e7c3f6117091 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -51,6 +51,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableFabricLogs() = 0; virtual bool enableFabricRenderer() = 0; virtual bool enableFontScaleChangesUpdatingLayout() = 0; + virtual bool enableIOSExperimentalAutoFocusImplementation() = 0; virtual bool enableIOSTextBaselineOffsetPerLine() = 0; virtual bool enableIOSViewClipToPaddingBox() = 0; virtual bool enableImagePrefetchingAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 5451b8c68cff..0925211f9346 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4b821513e808ca071104f413e15c2fd9>> + * @generated SignedSource<> */ /** @@ -174,6 +174,11 @@ bool NativeReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout( return ReactNativeFeatureFlags::enableFontScaleChangesUpdatingLayout(); } +bool NativeReactNativeFeatureFlags::enableIOSExperimentalAutoFocusImplementation( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableIOSExperimentalAutoFocusImplementation(); +} + bool NativeReactNativeFeatureFlags::enableIOSTextBaselineOffsetPerLine( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableIOSTextBaselineOffsetPerLine(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 844e1602154d..7c0f6dd50e2f 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<55da460bc2f8c915552eeae11f0b2e3e>> + * @generated SignedSource<> */ /** @@ -88,6 +88,8 @@ class NativeReactNativeFeatureFlags bool enableFontScaleChangesUpdatingLayout(jsi::Runtime& runtime); + bool enableIOSExperimentalAutoFocusImplementation(jsi::Runtime& runtime); + bool enableIOSTextBaselineOffsetPerLine(jsi::Runtime& runtime); bool enableIOSViewClipToPaddingBox(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 9c4788f67899..bc1bca520c90 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -325,6 +325,16 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + enableIOSExperimentalAutoFocusImplementation: { + defaultValue: false, + metadata: { + dateAdded: '2025-11-19', + description: 'Fixes #56595 by moving the autoFocus from didMoveToWindow to viewDidAppear', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'experimental', + }, enableIOSTextBaselineOffsetPerLine: { defaultValue: false, metadata: { diff --git a/packages/react-native/scripts/ios-prebuild/templates/React-umbrella.h b/packages/react-native/scripts/ios-prebuild/templates/React-umbrella.h index bcd298fd26f5..19898532a7b6 100644 --- a/packages/react-native/scripts/ios-prebuild/templates/React-umbrella.h +++ b/packages/react-native/scripts/ios-prebuild/templates/React-umbrella.h @@ -283,6 +283,7 @@ #import #import #import +#import FOUNDATION_EXPORT double ReactVersionNumber; FOUNDATION_EXPORT const unsigned char ReactVersionString[]; diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 0ab8c557bff4..4cfc3db58878 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<1d648095164f22868bbdf3500668bb14>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -73,6 +73,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ enableFabricLogs: Getter, enableFabricRenderer: Getter, enableFontScaleChangesUpdatingLayout: Getter, + enableIOSExperimentalAutoFocusImplementation: Getter, enableIOSTextBaselineOffsetPerLine: Getter, enableIOSViewClipToPaddingBox: Getter, enableImagePrefetchingAndroid: Getter, @@ -308,6 +309,10 @@ export const enableFabricRenderer: Getter = createNativeFlagGetter('ena * Enables font scale changes updating layout for measurable nodes. */ export const enableFontScaleChangesUpdatingLayout: Getter = createNativeFlagGetter('enableFontScaleChangesUpdatingLayout', true); +/** + * Fixes #56595 by moving the autoFocus from didMoveToWindow to viewDidAppear + */ +export const enableIOSExperimentalAutoFocusImplementation: Getter = createNativeFlagGetter('enableIOSExperimentalAutoFocusImplementation', false); /** * Applies base offset for each line of text separately on iOS. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index a268a1c5144a..92a4cb8c56cf 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5dea8e41a09f4ed658ce248121a2e981>> + * @generated SignedSource<<5974eabb1fcb69b9ebf76c144e7d63e7>> * @flow strict * @noformat */ @@ -51,6 +51,7 @@ export interface Spec extends TurboModule { +enableFabricLogs?: () => boolean; +enableFabricRenderer?: () => boolean; +enableFontScaleChangesUpdatingLayout?: () => boolean; + +enableIOSExperimentalAutoFocusImplementation?: () => boolean; +enableIOSTextBaselineOffsetPerLine?: () => boolean; +enableIOSViewClipToPaddingBox?: () => boolean; +enableImagePrefetchingAndroid?: () => boolean; diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index f2c8329be9a1..e8d381b3a7ca 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -325,6 +325,14 @@ category UIView(React) { public virtual void removeReactSubview:(UIView* subview); } +category UIViewController(React) { + public @property (assign, readonly) BOOL reactViewControllerIsVisible; + public virtual void reactAddViewControllerAppearanceListener:(id listener); + public virtual void reactNotifyViewControllerDidAppear:(BOOL animated); + public virtual void reactNotifyViewControllerDidDisappear:(BOOL animated); + public virtual void reactRemoveViewControllerAppearanceListener:(id listener); +} + class ObjCTimerRegistry : public facebook::react::PlatformTimerRegistry { public ObjCTimerRegistry(); public RCTTiming* _Null_unspecified timing; @@ -2467,6 +2475,9 @@ interface RCTViewComponentView : public UIView { public @property (weak) RCTBridge* bridge; public CGFloat RCTJSONParseOnlyNumber(id json); @@ -2530,7 +2541,7 @@ interface RCTWrapperView : public UIView { public virtual instancetype initWithBridge:(RCTBridge* bridge); } -interface RCTWrapperViewController : public UIViewController { +interface RCTWrapperViewController : public RCTViewController { public virtual instancetype initWithContentView:(UIView* contentView); } @@ -3493,6 +3504,11 @@ protocol RCTValueAnimatedNodeObserver : public NSObject { public virtual void animatedNode:didUpdateValue:(RCTValueAnimatedNode* node, CGFloat value); } +protocol RCTViewControllerAppearanceListener : public NSObject { + public virtual void reactViewControllerDidAppear:animated:(UIViewController* viewController, BOOL animated); + public virtual void reactViewControllerDidDisappear:animated:(UIViewController* viewController, BOOL animated); +} + protocol RCTVirtualViewContainerProtocol { public virtual RCTVirtualViewContainerState* virtualViewContainerState(); } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index b7e4ab668f81..ac156f189fdc 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -325,6 +325,14 @@ category UIView(React) { public virtual void removeReactSubview:(UIView* subview); } +category UIViewController(React) { + public @property (assign, readonly) BOOL reactViewControllerIsVisible; + public virtual void reactAddViewControllerAppearanceListener:(id listener); + public virtual void reactNotifyViewControllerDidAppear:(BOOL animated); + public virtual void reactNotifyViewControllerDidDisappear:(BOOL animated); + public virtual void reactRemoveViewControllerAppearanceListener:(id listener); +} + class ObjCTimerRegistry : public facebook::react::PlatformTimerRegistry { public ObjCTimerRegistry(); public RCTTiming* _Null_unspecified timing; @@ -2467,6 +2475,9 @@ interface RCTViewComponentView : public UIView { public @property (weak) RCTBridge* bridge; public CGFloat RCTJSONParseOnlyNumber(id json); @@ -2530,7 +2541,7 @@ interface RCTWrapperView : public UIView { public virtual instancetype initWithBridge:(RCTBridge* bridge); } -interface RCTWrapperViewController : public UIViewController { +interface RCTWrapperViewController : public RCTViewController { public virtual instancetype initWithContentView:(UIView* contentView); } @@ -3493,6 +3504,11 @@ protocol RCTValueAnimatedNodeObserver : public NSObject { public virtual void animatedNode:didUpdateValue:(RCTValueAnimatedNode* node, CGFloat value); } +protocol RCTViewControllerAppearanceListener : public NSObject { + public virtual void reactViewControllerDidAppear:animated:(UIViewController* viewController, BOOL animated); + public virtual void reactViewControllerDidDisappear:animated:(UIViewController* viewController, BOOL animated); +} + protocol RCTVirtualViewContainerProtocol { public virtual RCTVirtualViewContainerState* virtualViewContainerState(); }