Skip to content

Commit 33e0521

Browse files
zoontekfacebook-github-bot
authored andcommitted
Add view getter on RCTRootView / RCTFabricSurfaceHostingProxyRootView (#37310)
Summary: Hi 👋 During the [react-native-bootsplash](https://github.com/zoontek/react-native-bootsplash) implementation of the new architecture, I noticed a few thing regarding `RCTRootView` / `RCTFabricSurfaceHostingProxyRootView` compat. Currently `RCTRootView` inherits from `UIView`, but `RCTFabricSurfaceHostingProxyRootView` does not, which this works: ```obj-c - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps { RCTRootView *rootView = (RCTRootView *) [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps]; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil]; UIView *loadingView = [[storyboard instantiateInitialViewController] view]; loadingView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; loadingView.frame = rootView.bounds; loadingView.center = (CGPoint){CGRectGetMidX(rootView.bounds), CGRectGetMidY(rootView.bounds)}; loadingView.hidden = NO; [rootView addSubview:loadingView]; return rootView; } ``` But this doesn't: ```obj-c - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps { RCTFabricSurfaceHostingProxyRootView *rootView = (RCTFabricSurfaceHostingProxyRootView *) [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps]; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil]; UIView *loadingView = [[storyboard instantiateInitialViewController] view]; loadingView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; loadingView.frame = rootView.bounds; loadingView.center = (CGPoint){CGRectGetMidX(rootView.bounds), CGRectGetMidY(rootView.bounds)}; loadingView.hidden = NO; [rootView addSubview:loadingView]; return rootView; } ``` Because `RCTFabricSurfaceHostingProxyRootView` is an imperfect proxy as it doesn't give access to the underlaying `UIView *`. As a solution, I added a prop on both: `UIView *view` PS: I'm well aware that `setLoadingView` also exists in both files, but it's currently not usable as the current `isActivityIndicatorViewVisible` / `isSurfaceViewVisible` / `_activityIndicatorViewFactory` logic in `RCTSurfaceHostingView.mm` doesn't work: a situation where `isActivityIndicatorViewVisible == true && isSurfaceViewVisible == false && _activityIndicatorViewFactory != nil` never happen: <img width="1162" alt="Screenshot_2023-05-06_at_18 10 18" src="https://user-images.githubusercontent.com/1902323/236883439-2256ddfb-7846-482a-b957-002a7d51a148.png"> ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: #37310 Test Plan: Add this block of code in `AppDelegate.mm`: ```obj-c #import <React/RCTRootView.h> #if __has_include(<React/RCTFabricSurfaceHostingProxyRootView.h>) #import <React/RCTFabricSurfaceHostingProxyRootView.h> #endif // … - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps { #ifdef RCT_NEW_ARCH_ENABLED RCTFabricSurfaceHostingProxyRootView *rootView = (RCTFabricSurfaceHostingProxyRootView *) #else RCTRootView *rootView = (RCTRootView *) #endif [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps]; // accessing the "real" root view on both arch UIView *view = rootView.view; UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil]; UIView *loadingView = [[storyboard instantiateInitialViewController] view]; loadingView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; loadingView.frame = view.bounds; loadingView.center = (CGPoint){CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds)}; loadingView.hidden = NO; [view addSubview:loadingView]; return rootView; } ``` It should persist the splash screen on both old and new architecture. Reviewed By: sammy-SC Differential Revision: D45688644 Pulled By: cipolleschi fbshipit-source-id: b6f2fc8091a15189ea2eceb8ea426593f62674cb
1 parent d2e446d commit 33e0521

File tree

4 files changed

+16
-0
lines changed

4 files changed

+16
-0
lines changed

packages/react-native/React/Base/RCTRootView.h

+5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ extern
133133
*/
134134
@property (nonatomic, weak, nullable) UIViewController *reactViewController;
135135

136+
/**
137+
* The root view casted as UIView. Used by splash screen libraries.
138+
*/
139+
@property (nonatomic, strong, readonly) UIView *view;
140+
136141
/**
137142
* The React-managed contents view of the root view.
138143
*/

packages/react-native/React/Base/RCTRootView.m

+5
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ - (instancetype)initWithBundleURL:(NSURL *)bundleURL
116116
RCT_NOT_IMPLEMENTED(-(instancetype)initWithFrame : (CGRect)frame)
117117
RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
118118

119+
- (UIView *)view
120+
{
121+
return self;
122+
}
123+
119124
- (BOOL)hasBridge
120125
{
121126
return _bridge != nil;

packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
3434
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
3535
@property (nonatomic, weak) id<RCTRootViewDelegate> delegate;
3636
@property (nonatomic, weak) UIViewController *reactViewController;
37+
@property (nonatomic, strong, readonly) UIView *view;
3738
@property (nonatomic, strong, readonly) UIView *contentView;
3839
@property (nonatomic, strong) UIView *loadingView;
3940
@property (nonatomic, assign) BOOL passThroughTouches;

packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm

+5
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ - (NSString *)moduleName
134134
return super.surface.moduleName;
135135
}
136136

137+
- (UIView *)view
138+
{
139+
return (UIView *)super.surface.view;
140+
}
141+
137142
- (UIView *)contentView
138143
{
139144
return self;

0 commit comments

Comments
 (0)