Skip to content

Commit db9c9ea

Browse files
cipolleschifacebook-github-bot
authored andcommitted
Add function to customise RootView in Bridgeless (#42088)
Summary: Pull Request resolved: #42088 This change adds an extra function to customise the RootView in both Bridge and Bridgeless mode. To nudge users in a migration, we also add a warning message for next version that should push our users to migrate away from the old implementation to the new one. *The Warning is shown ONLY when the user do customise the rootView*. For users which were not customising the Root View, the warning will not appear. The documentation of the new method plus the warning should guide the users toward the right migration path. ## Changelog [iOS][Added] - Added the customiseRootView method which is called in both bridge and bridgeless. Added also a warning for 0.74 with instructions on how to migrate. Reviewed By: cortinico Differential Revision: D52442598 fbshipit-source-id: 8b99b67f4741ee61989a8659a3d74c1eba27bc5b
1 parent af8c56a commit db9c9ea

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h

+21
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
@class RCTBridge;
1212
@protocol RCTBridgeDelegate;
1313
@protocol RCTComponentViewProtocol;
14+
@class RCTRootView;
1415
@class RCTSurfacePresenterBridgeAdapter;
1516

1617
/**
@@ -86,6 +87,26 @@
8687
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
8788
moduleName:(NSString *)moduleName
8889
initProps:(NSDictionary *)initProps;
90+
/**
91+
* This method can be used to customize the rootView that is passed to React Native.
92+
* A typical example is to override this method in the AppDelegate to change the background color.
93+
* To achieve this, add in your `AppDelegate.mm`:
94+
* ```
95+
* - (void)customizeRootView:(RCTRootView *)rootView
96+
* {
97+
* rootView.backgroundColor = [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
98+
* if ([traitCollection userInterfaceStyle] == UIUserInterfaceStyleDark) {
99+
* return [UIColor blackColor];
100+
* } else {
101+
* return [UIColor whiteColor];
102+
* }
103+
* }];
104+
* }
105+
* ```
106+
*
107+
* @parameter: rootView - The root view to customize.
108+
*/
109+
- (void)customizeRootView:(RCTRootView *)rootView;
89110

90111
/**
91112
* It creates the RootViewController.

packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm

+23
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#import "RCTAppDelegate.h"
99
#import <React/RCTCxxBridgeDelegate.h>
10+
#import <React/RCTLog.h>
1011
#import <React/RCTRootView.h>
1112
#import <React/RCTSurfacePresenterBridgeAdapter.h>
1213
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
@@ -117,6 +118,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
117118
}
118119
rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps];
119120
}
121+
[self customizeRootView:(RCTRootView *)rootView];
120122
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
121123
UIViewController *rootViewController = [self createRootViewController];
122124
[self setRootView:rootView toRootViewController:rootViewController];
@@ -144,10 +146,16 @@ - (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOp
144146
return [[RCTBridge alloc] initWithDelegate:delegate launchOptions:launchOptions];
145147
}
146148

149+
- (void)customizeRootView:(RCTRootView *)rootView
150+
{
151+
// Override point for customization after application launch.
152+
}
153+
147154
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
148155
moduleName:(NSString *)moduleName
149156
initProps:(NSDictionary *)initProps
150157
{
158+
[self _logWarnIfCreateRootViewWithBridgeIsOverridden];
151159
BOOL enableFabric = self.fabricEnabled;
152160
UIView *rootView = RCTAppSetupDefaultRootView(bridge, moduleName, initProps, enableFabric);
153161

@@ -156,6 +164,21 @@ - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
156164
return rootView;
157165
}
158166

167+
// TODO T173939093 - Remove _logWarnIfCreateRootViewWithBridgeIsOverridden after 0.74 is cut
168+
- (void)_logWarnIfCreateRootViewWithBridgeIsOverridden
169+
{
170+
SEL selector = @selector(createRootViewWithBridge:moduleName:initProps:);
171+
IMP baseClassImp = method_getImplementation(class_getInstanceMethod([RCTAppDelegate class], selector));
172+
IMP currentClassImp = method_getImplementation(class_getInstanceMethod([self class], selector));
173+
if (currentClassImp != baseClassImp) {
174+
NSString *warnMessage =
175+
@"If you are using the `createRootViewWithBridge` to customize the root view appearence,"
176+
"for example to set the backgroundColor, please migrate to `customiseView` method.\n"
177+
"The `createRootViewWithBridge` method is not invoked in bridgeless.";
178+
RCTLogWarn(@"%@", warnMessage);
179+
}
180+
}
181+
159182
- (UIViewController *)createRootViewController
160183
{
161184
return [UIViewController new];

0 commit comments

Comments
 (0)