Skip to content

Commit d0a32c2

Browse files
tido64facebook-github-bot
authored andcommitted
iOS: Make RCTKeyWindow multi-window aware and add UIScene support to RCTRedBox (#28147)
Summary: `RCTRedBox` doesn't appear in apps implementing `UISceneDelegate`. ## Changelog [iOS] [Changed] - `RCTKeyWindow()` is now multi-window aware [iOS] [Fixed] - `RCTRedBox` doesn't appear in apps implementing `UISceneDelegate` Pull Request resolved: #28147 Test Plan: - Trigger an error in RNTester - Trigger an error in an app implementing `UISceneDelegate` ![Simulator Screen Shot - iPhone 11 Pro Max - 2020-02-21 at 14 17 54](https://user-images.githubusercontent.com/4123478/75037702-14066a80-54b5-11ea-9373-b56b467be845.png) Reviewed By: PeteTheHeat Differential Revision: D20036399 Pulled By: hramos fbshipit-source-id: 07d83e985b02296f930114e3c7100c2077e82300
1 parent 74b667d commit d0a32c2

File tree

2 files changed

+31
-29
lines changed

2 files changed

+31
-29
lines changed

React/Base/RCTUtils.m

+6-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,12 @@ BOOL RCTRunningInAppExtension(void)
497497
}
498498

499499
// TODO: replace with a more robust solution
500-
return RCTSharedApplication().keyWindow;
500+
for (UIWindow *window in RCTSharedApplication().windows) {
501+
if (window.keyWindow) {
502+
return window;
503+
}
504+
}
505+
return nil;
501506
}
502507

503508
UIViewController *__nullable RCTPresentedViewController(void)

React/CoreModules/RCTRedBox.mm

+25-28
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ - (void)loadExtraDataViewController;
7070

7171
@end
7272

73-
@interface RCTRedBoxWindow : UIWindow <UITableViewDelegate, UITableViewDataSource>
73+
@interface RCTRedBoxWindow : NSObject <UITableViewDelegate, UITableViewDataSource>
74+
@property (nonatomic, strong) UIViewController *rootViewController;
7475
@property (nonatomic, weak) id<RCTRedBoxWindowActionDelegate> actionDelegate;
7576
@end
7677

@@ -82,22 +83,17 @@ @implementation RCTRedBoxWindow
8283
int _lastErrorCookie;
8384
}
8485

85-
- (instancetype)initWithFrame:(CGRect)frame customButtonTitles:(NSArray<NSString *>*)customButtonTitles customButtonHandlers:(NSArray<RCTRedBoxButtonPressHandler> *)customButtonHandlers
86+
- (instancetype)initWithFrame:(CGRect)frame
87+
customButtonTitles:(NSArray<NSString *>*)customButtonTitles
88+
customButtonHandlers:(NSArray<RCTRedBoxButtonPressHandler> *)customButtonHandlers
8689
{
87-
_lastErrorCookie = -1;
88-
if ((self = [super initWithFrame:frame])) {
89-
#if TARGET_OS_TV
90-
self.windowLevel = UIWindowLevelAlert + 1000;
91-
#else
92-
self.windowLevel = UIWindowLevelStatusBar - 1;
93-
#endif
94-
self.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
95-
self.hidden = YES;
90+
if (self = [super init]) {
91+
_lastErrorCookie = -1;
9692

97-
UIViewController *rootController = [UIViewController new];
98-
self.rootViewController = rootController;
99-
UIView *rootView = rootController.view;
100-
rootView.backgroundColor = [UIColor clearColor];
93+
_rootViewController = [UIViewController new];
94+
UIView *rootView = _rootViewController.view;
95+
rootView.frame = frame;
96+
rootView.backgroundColor = [UIColor blackColor];
10197

10298
const CGFloat buttonHeight = 60;
10399

@@ -133,8 +129,8 @@ - (instancetype)initWithFrame:(CGRect)frame customButtonTitles:(NSArray<NSString
133129
UIButton *copyButton = [self redBoxButton:copyText accessibilityIdentifier:@"redbox-copy" selector:@selector(copyStack) block:nil];
134130
UIButton *extraButton = [self redBoxButton:extraText accessibilityIdentifier:@"redbox-extra" selector:@selector(showExtraDataViewController) block:nil];
135131

136-
CGFloat buttonWidth = self.bounds.size.width / (4 + [customButtonTitles count]);
137-
CGFloat bottomButtonHeight = self.bounds.size.height - buttonHeight - [self bottomSafeViewHeight];
132+
CGFloat buttonWidth = frame.size.width / (4 + [customButtonTitles count]);
133+
CGFloat bottomButtonHeight = frame.size.height - buttonHeight - [self bottomSafeViewHeight];
138134
dismissButton.frame = CGRectMake(0, bottomButtonHeight, buttonWidth, buttonHeight);
139135
reloadButton.frame = CGRectMake(buttonWidth, bottomButtonHeight, buttonWidth, buttonHeight);
140136
copyButton.frame = CGRectMake(buttonWidth * 2, bottomButtonHeight, buttonWidth, buttonHeight);
@@ -158,7 +154,7 @@ - (instancetype)initWithFrame:(CGRect)frame customButtonTitles:(NSArray<NSString
158154

159155
UIView *bottomSafeView = [UIView new];
160156
bottomSafeView.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
161-
bottomSafeView.frame = CGRectMake(0, self.bounds.size.height - [self bottomSafeViewHeight], self.bounds.size.width, [self bottomSafeViewHeight]);
157+
bottomSafeView.frame = CGRectMake(0, frame.size.height - [self bottomSafeViewHeight], frame.size.width, [self bottomSafeViewHeight]);
162158

163159
[rootView addSubview:bottomSafeView];
164160
}
@@ -209,15 +205,18 @@ - (NSString *)stripAnsi:(NSString *)text
209205
return [regex stringByReplacingMatchesInString:text options:0 range:NSMakeRange(0, [text length]) withTemplate:@""];
210206
}
211207

212-
- (void)showErrorMessage:(NSString *)message withStack:(NSArray<RCTJSStackFrame *> *)stack isUpdate:(BOOL)isUpdate errorCookie:(int)errorCookie
208+
- (void)showErrorMessage:(NSString *)message
209+
withStack:(NSArray<RCTJSStackFrame *> *)stack
210+
isUpdate:(BOOL)isUpdate
211+
errorCookie:(int)errorCookie
213212
{
214213
// Remove ANSI color codes from the message
215214
NSString *messageWithoutAnsi = [self stripAnsi:message];
216215

217216
// Show if this is a new message, or if we're updating the previous message
218-
BOOL isNew = self.hidden && !isUpdate;
217+
BOOL isNew = !self.rootViewController.isBeingPresented && !isUpdate;
219218
BOOL isUpdateForSameMessage = !isNew && (
220-
!self.hidden && isUpdate && (
219+
self.rootViewController.isBeingPresented && isUpdate && (
221220
(errorCookie == -1 && [_lastErrorMessage isEqualToString:messageWithoutAnsi]) ||
222221
(errorCookie == _lastErrorCookie)
223222
)
@@ -231,22 +230,20 @@ - (void)showErrorMessage:(NSString *)message withStack:(NSArray<RCTJSStackFrame
231230

232231
[_stackTraceTableView reloadData];
233232

234-
if (self.hidden) {
233+
if (!self.rootViewController.isBeingPresented) {
235234
[_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
236235
atScrollPosition:UITableViewScrollPositionTop
237236
animated:NO];
237+
[RCTKeyWindow().rootViewController presentViewController:self.rootViewController
238+
animated:YES
239+
completion:nil];
238240
}
239-
240-
[self makeKeyAndVisible];
241-
[self becomeFirstResponder];
242241
}
243242
}
244243

245244
- (void)dismiss
246245
{
247-
self.hidden = YES;
248-
[self resignFirstResponder];
249-
[RCTSharedApplication().delegate.window makeKeyWindow];
246+
[self.rootViewController dismissViewControllerAnimated:YES completion:nil];
250247
}
251248

252249
- (void)reload

0 commit comments

Comments
 (0)