feat(iOS): refactor RCTDevLoadingView to use constraints (#46621)

Summary:
This PR refactors the RCTDevLoadingView to use constraints instead of explicitly defining frames.

Now the code looks like this:

```
#if TARGET_OS_MACCATALYST
      self->_window.frame = CGRectMake(0, window.safeAreaInsets.top, windowWidth, 20);
      self->_label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, windowWidth, 20)];
#else
      self->_window.frame = CGRectMake(0, 0, windowWidth, window.safeAreaInsets.top + 10);
      self->_label = [[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top - 10, windowWidth, 20)];
#endif
```

When working with visionOS I quickly found my self in the need of adding additional else there...

This PR uses constraints to layout the views correctly for every device.

| Device         | Screenshot |
| -------------- | ---------- |
| iOS | <img src="https://github.com/user-attachments/assets/decc146e-41a2-4ce8-bafd-77c77a39398b" width="200"/> |
| macOS Catalyst | <img src="https://github.com/user-attachments/assets/78ef4946-a6dc-49a2-864e-a483577798f1" width="200"/> |
| iPadOS | <img src="https://github.com/user-attachments/assets/a15bd1a8-84ae-47d0-becb-e14c3a9352d4" width="200"/>  |
| visionOS | <img src="https://github.com/user-attachments/assets/d74f0607-837e-4f7b-b924-fc6fce80d763" width="200"/>  |

## Changelog:

[IOS] [CHANGED] - refactor RCTDevLoadingView to use constraints

Pull Request resolved: https://github.com/facebook/react-native/pull/46621

Test Plan: Test if DevLoading view is properly showing up

Reviewed By: blakef

Differential Revision: D63383002

Pulled By: cipolleschi

fbshipit-source-id: b17499e12d4a882facce4c45b1cc22eb43ea3bb1
This commit is contained in:
Oskar Kwaśniewski
2024-09-30 08:26:45 -07:00
committed by Facebook GitHub Bot
parent 4caf548a9f
commit fbda60e657
@@ -6,6 +6,7 @@
*/
#import <React/RCTDevLoadingView.h>
#include <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@@ -30,6 +31,7 @@ using namespace facebook::react;
@implementation RCTDevLoadingView {
UIWindow *_window;
UILabel *_label;
UIView *_container;
NSDate *_showDate;
BOOL _hiding;
dispatch_block_t _initialMessageBlock;
@@ -112,38 +114,53 @@ RCT_EXPORT_MODULE()
}
dispatch_async(dispatch_get_main_queue(), ^{
self->_showDate = [NSDate date];
if (!self->_window && !RCTRunningInTestEnvironment()) {
UIWindow *window = RCTKeyWindow();
CGFloat windowWidth = window.bounds.size.width;
self->_window = [[UIWindow alloc] initWithWindowScene:window.windowScene];
#if TARGET_OS_MACCATALYST
self->_window.frame = CGRectMake(0, window.safeAreaInsets.top, windowWidth, 20);
self->_label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, windowWidth, 20)];
#else
self->_window.frame = CGRectMake(0, 0, windowWidth, window.safeAreaInsets.top + 10);
self->_label = [[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top - 10, windowWidth, 20)];
#endif
[self->_window addSubview:self->_label];
self->_window.windowLevel = UIWindowLevelStatusBar + 1;
// set a root VC so rotation is supported
self->_window.rootViewController = [UIViewController new];
self->_label.font = [UIFont monospacedDigitSystemFontOfSize:12.0 weight:UIFontWeightRegular];
self->_label.textAlignment = NSTextAlignmentCenter;
if (RCTRunningInTestEnvironment()) {
return;
}
self->_label.text = message;
self->_showDate = [NSDate date];
UIWindow *mainWindow = RCTKeyWindow();
self->_window = [[UIWindow alloc] initWithWindowScene:mainWindow.windowScene];
self->_window.windowLevel = UIWindowLevelStatusBar + 1;
self->_window.rootViewController = [UIViewController new];
self->_container = [[UIView alloc] init];
self->_container.backgroundColor = backgroundColor;
self->_container.translatesAutoresizingMaskIntoConstraints = NO;
self->_label = [[UILabel alloc] init];
self->_label.translatesAutoresizingMaskIntoConstraints = NO;
self->_label.font = [UIFont monospacedDigitSystemFontOfSize:12.0 weight:UIFontWeightRegular];
self->_label.textAlignment = NSTextAlignmentCenter;
self->_label.textColor = color;
self->_label.text = message;
[self->_window.rootViewController.view addSubview:self->_container];
[self->_container addSubview:self->_label];
CGFloat topSafeAreaHeight = mainWindow.safeAreaInsets.top;
CGFloat height = topSafeAreaHeight + 25;
self->_window.frame = CGRectMake(0, 0, mainWindow.frame.size.width, height);
self->_window.backgroundColor = backgroundColor;
self->_window.hidden = NO;
});
[self hideBannerAfter:15.0];
[self->_window layoutIfNeeded];
[NSLayoutConstraint activateConstraints:@[
// Container constraints
[self->_container.topAnchor constraintEqualToAnchor:self->_window.rootViewController.view.topAnchor],
[self->_container.leadingAnchor constraintEqualToAnchor:self->_window.rootViewController.view.leadingAnchor],
[self->_container.trailingAnchor constraintEqualToAnchor:self->_window.rootViewController.view.trailingAnchor],
[self->_container.heightAnchor constraintEqualToConstant:height],
// Label constraints
[self->_label.centerXAnchor constraintEqualToAnchor:self->_container.centerXAnchor],
[self->_label.bottomAnchor constraintEqualToAnchor:self->_container.bottomAnchor constant:-5],
]];
[self hideBannerAfter:15.0];
});
}
RCT_EXPORT_METHOD(showMessage