Skip to content

Commit

Permalink
Allow the app to control the Activity Indicator in Bridgeless mode (#…
Browse files Browse the repository at this point in the history
…43195)

Summary:
Pull Request resolved: #43195

Right now, the activity indicator is automatically hidden when the view is ready to be shown in bridgeless mode.
There is no way to prevent that the activity indicator is automatically removed.

In OSS, we have libraries (e.g.: `react-native-bootsplash`) that will allow the app to control when and how dismiss the splashscreen, but due to the current automatic behavior on Bridgeless, they stopped working.

***Note:** In the previous implementation, they were working because instead of using the `loadingView` property, they were adding the splashscreen view on top of the existing one. However, with the lazy behavior of the bridgeless mode, this is not working anymore because the RCTMountingManager [expect not to have any subview](https://www.internalfb.com/code/fbsource/[6962fa457dbc74ab3a760cf6090d9643c6748781]/xplat/js/react-native-github/packages/react-native/React/Fabric/Mounting/RCTMountingManager.mm?lines=176) when the first surface is mounted.*

## Changelog
[iOS][Added] - Allow the activityIndicator to be controlled from JS in bridgeless mode

Reviewed By: philIip

Differential Revision: D54191856

fbshipit-source-id: 14738032f04adf7eaf7d200d889acd752aed0ed3
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Mar 5, 2024
1 parent 1387725 commit 9aeb9f2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, copy, nullable) RCTSurfaceHostingViewActivityIndicatorViewFactory activityIndicatorViewFactory;

/**
* When set to `YES`, the activity indicator is not automatically hidden when the Surface stage changes.
* In this scenario, users should invoke `hideActivityIndicator` to remove it.
*
* @param disabled: if `YES`, the auto-hide is disabled. Otherwise the loading view will be hidden automatically
*/
- (void)disableActivityIndicatorAutoHide:(BOOL)disabled;
@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ @implementation RCTSurfaceHostingView {
UIView *_Nullable _activityIndicatorView;
UIView *_Nullable _surfaceView;
RCTSurfaceStage _stage;
BOOL _autoHideDisabled;
}

RCT_NOT_IMPLEMENTED(-(instancetype)init)
Expand All @@ -36,6 +37,7 @@ - (instancetype)initWithSurface:(id<RCTSurfaceProtocol>)surface
if (self = [super initWithFrame:CGRectZero]) {
_surface = surface;
_sizeMeasureMode = sizeMeasureMode;
_autoHideDisabled = NO;

_surface.delegate = self;
_stage = surface.stage;
Expand Down Expand Up @@ -124,6 +126,10 @@ - (void)setSizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode
_sizeMeasureMode = sizeMeasureMode;
[self _invalidateLayout];
}
- (void)disableActivityIndicatorAutoHide:(BOOL)disabled
{
_autoHideDisabled = disabled;
}

#pragma mark - isActivityIndicatorViewVisible

Expand Down Expand Up @@ -162,7 +168,16 @@ - (void)setIsSurfaceViewVisible:(BOOL)visible
_surfaceView = _surface.view;
_surfaceView.frame = self.bounds;
_surfaceView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:_surfaceView];
if (_activityIndicatorView && _autoHideDisabled) {
// The activity indicator is still showing and the surface is set to
// prevent the auto hide. This means that the application will take care of
// hiding it when it's ready.
// Let's add the surfaceView below the activity indicator so it's ready once
// the activity indicator is hidden.
[self insertSubview:_surfaceView belowSubview:_activityIndicatorView];
} else {
[self addSubview:_surfaceView];
}
} else {
[_surfaceView removeFromSuperview];
_surfaceView = nil;
Expand Down Expand Up @@ -204,7 +219,7 @@ - (void)_invalidateLayout
- (void)_updateViews
{
self.isSurfaceViewVisible = RCTSurfaceStageIsRunning(_stage);
self.isActivityIndicatorViewVisible = RCTSurfaceStageIsPreparing(_stage);
self.isActivityIndicatorViewVisible = _autoHideDisabled || RCTSurfaceStageIsPreparing(_stage);
}

- (void)didMoveToWindow
Expand Down

0 comments on commit 9aeb9f2

Please sign in to comment.