Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the app to control the Activity Indicator in Bridgeless mode #43195

Closed
wants to merge 1 commit into from

Conversation

cipolleschi
Copy link
Contributor

Summary:
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 when the first surface is mounted.

Changelog

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

Differential Revision: D54191856

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 26, 2024
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@cipolleschi
Copy link
Contributor Author

@zoontek After these changes are landed, you'll need the following changes in your RNBootSplash.mm file:

#else
#import <React/RCTRootView.h>
#endif
+ #import "RCTAppDelegate.h"

// ...

 + (void)initWithStoryboard:(NSString * _Nonnull)storyboardName
                  rootView:(UIView * _Nullable)rootView {
// ...

#ifdef RCT_NEW_ARCH_ENABLED
    if (rootView != nil && [rootView isKindOfClass:[RCTSurfaceHostingProxyRootView class]]) {
+      ((RCTSurfaceHostingProxyRootView *)rootView).preventAutoHide = YES;
      _rootView = (RCTSurfaceHostingProxyRootView *)rootView;
#else

// ...

      _loadingView.center = (CGPoint){CGRectGetMidX(_rootView.bounds), CGRectGetMidY(_rootView.bounds)};
      _loadingView.hidden = NO;

+      RCTAppDelegate * appDelegate = (RCTAppDelegate *)[RCTSharedApplication() delegate];
+      if ([appDelegate bridgelessEnabled]) {
+        ((RCTRootView *)_rootView).loadingView = _loadingView;
+      } else {
-      [_rootView addSubview:_loadingView];
+       [_rootView addSubview:_loadingView];
+      }

      [[NSNotificationCenter defaultCenter] addObserver:self
                                               selector:@selector(onJavaScriptDidLoad)
                                                   name:RCTJavaScriptDidLoadNotification
                                                 object:nil];

And then it should work as expected.

If you want, you can also try to pick these changes and apply them to your examples and see how they behave.

Let me know if something like this might work.


The reason why we have to check whether bridgeless is enabled or not is because the Surface lifecycle is different between the Bridge and Bridgeless mode.
Unfortunately, in bridge mode, the loading view is shown and hidden before the customizeView method is invoked.
Moreover, it is shown and hidden within the creation of the RCTSurfaceHostingProxyRootView, and I could not find any hook we can attach to.

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@property (nonatomic, assign) BOOL preventActivityIndicatorAutoHide;

/**
* This method hides the activity indicator and remoes it from the view hierarchy.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small typo here: removes

}
}

- (void)hideActivityIndicator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naïve question here, but is there a reason there's 2 different wording? setLoadingView, but hideActivityIndicator. This could be misleading, especially with

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@zoontek
Copy link
Contributor

zoontek commented Feb 26, 2024

@cipolleschi LGTM!

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

cipolleschi added a commit to cipolleschi/react-native that referenced this pull request Mar 5, 2024
…acebook#43195)

Summary:

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
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

…acebook#43195)

Summary:

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
cipolleschi added a commit to cipolleschi/react-native that referenced this pull request Mar 5, 2024
…acebook#43195)

Summary:

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
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D54191856

@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Mar 5, 2024
@facebook-github-bot
Copy link
Contributor

This pull request has been merged in 9aeb9f2.

huntie pushed a commit that referenced this pull request Mar 18, 2024
…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
This was referenced Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. p: Facebook Partner: Facebook Partner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants