diff --git a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm index e30afb417a54a8..a281d44535563e 100644 --- a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm +++ b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm @@ -116,19 +116,17 @@ - (void)showMessage:(NSString *)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; - UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)]; - [self->_container addGestureRecognizer:tapGesture]; - self->_container.userInteractionEnabled = YES; - - if (dismissButton) { + if (!self->_label) { + self->_label = [[UILabel alloc] init]; + self->_label.translatesAutoresizingMaskIntoConstraints = NO; + self->_label.font = [UIFont monospacedDigitSystemFontOfSize:12.0 weight:UIFontWeightRegular]; + self->_label.textAlignment = NSTextAlignmentCenter; + self->_label.numberOfLines = 0; + } + self->_label.textColor = color; + self->_label.text = message; + + if (!self->_dismissButton) { CGFloat hue = 0.0; CGFloat saturation = 0.0; CGFloat brightness = 0.0; @@ -154,52 +152,61 @@ - (void)showMessage:(NSString *)message self->_dismissButton = [UIButton buttonWithConfiguration:buttonConfig primaryAction:dismissAction]; self->_dismissButton.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->_label.numberOfLines = 0; - - [self->_window.rootViewController.view addSubview:self->_container]; - if (dismissButton) { + self->_dismissButton.hidden = !dismissButton; + + if (!self->_container) { + self->_container = [[UIView alloc] init]; + self->_container.translatesAutoresizingMaskIntoConstraints = NO; + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)]; + [self->_container addGestureRecognizer:tapGesture]; + self->_container.userInteractionEnabled = YES; + [self->_container addSubview:self->_label]; [self->_container addSubview:self->_dismissButton]; } - [self->_container addSubview:self->_label]; + self->_container.backgroundColor = backgroundColor; + UIWindow *mainWindow = RCTKeyWindow(); + if (!self->_window) { + self->_window = [[UIWindow alloc] initWithWindowScene:mainWindow.windowScene]; + self->_window.windowLevel = UIWindowLevelStatusBar + 1; + self->_window.rootViewController = [UIViewController new]; + [self->_window.rootViewController.view addSubview:self->_container]; + } CGFloat topSafeAreaHeight = mainWindow.safeAreaInsets.top; - self->_window.hidden = NO; - - [self->_window layoutIfNeeded]; - - NSMutableArray *constraints = [NSMutableArray arrayWithArray:@[ - // 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], - + + // These constraints may update on each call, while the rest are constant + // (so only need to be activated once). + NSMutableArray *constraints = [NSMutableArray arrayWithArray: @[ + // Dismiss button constraints + [self->_label.trailingAnchor constraintEqualToAnchor:dismissButton ? self->_dismissButton.leadingAnchor : self->_container.trailingAnchor + constant:-10], + // Label constraints [self->_label.topAnchor constraintEqualToAnchor:self->_container.topAnchor constant:topSafeAreaHeight + 8], - [self->_label.leadingAnchor constraintEqualToAnchor:self->_container.leadingAnchor constant:10], - [self->_label.bottomAnchor constraintEqualToAnchor:self->_container.bottomAnchor constant:-8], ]]; - - // Add button-specific constraints if button exists - if (dismissButton) { + + if (!self->_constraintsActivated) { [constraints addObjectsFromArray:@[ + // Dismiss button constraints [self->_dismissButton.trailingAnchor constraintEqualToAnchor:self->_container.trailingAnchor constant:-10], [self->_dismissButton.centerYAnchor constraintEqualToAnchor:self->_label.centerYAnchor], [self->_dismissButton.heightAnchor constraintEqualToConstant:22], - [self->_label.trailingAnchor constraintEqualToAnchor:self->_dismissButton.leadingAnchor constant:-10], + + // 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], + + // Label constraints + [self->_label.leadingAnchor constraintEqualToAnchor:self->_container.leadingAnchor constant:10], + [self->_label.bottomAnchor constraintEqualToAnchor:self->_container.bottomAnchor constant:-8], ]]; - } else { - [constraints addObject:[self->_label.trailingAnchor constraintEqualToAnchor:self->_container.trailingAnchor - constant:-10]]; } - [NSLayoutConstraint activateConstraints:constraints]; + self->_constraintsActivated = YES; + + self->_window.hidden = NO; + [self->_window layoutIfNeeded]; }); }