mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Make RCTRedBox customizable
Summary: Adds the ability to add extra buttons and renders them along with the other buttons. Changelog: [iOS] [Added] - RCTRedBox ability to add extra buttons Reviewed By: PeteTheHeat Differential Revision: D17935352 fbshipit-source-id: f8fb28653e535cd2c098566afbc639eb5c196228
This commit is contained in:
committed by
Facebook Github Bot
parent
ef3f80abc1
commit
fc80a51457
@@ -13,6 +13,8 @@
|
||||
|
||||
@class RCTJSStackFrame;
|
||||
|
||||
typedef void (^RCTRedBoxButtonPressHandler)(void);
|
||||
|
||||
@interface RCTRedBox : NSObject <RCTBridgeModule>
|
||||
|
||||
- (void)registerErrorCustomizer:(id<RCTErrorCustomizer>)errorCustomizer;
|
||||
@@ -32,6 +34,8 @@
|
||||
|
||||
- (void)dismiss;
|
||||
|
||||
- (void)addCustomButton:(NSString *)title onPressHandler:(RCTRedBoxButtonPressHandler)handler;
|
||||
|
||||
/** Overrides bridge.bundleURL. Modify on main thread only. You shouldn't need to use this. */
|
||||
@property (nonatomic, strong) NSURL *overrideBundleURL;
|
||||
|
||||
|
||||
+75
-13
@@ -16,6 +16,8 @@
|
||||
#import "RCTRedBoxExtraDataViewController.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#if RCT_DEV
|
||||
static BOOL redBoxEnabled = YES;
|
||||
#else
|
||||
@@ -34,6 +36,41 @@ BOOL RCTRedBoxGetEnabled() {
|
||||
|
||||
@class RCTRedBoxWindow;
|
||||
|
||||
@interface UIButton (RCTRedBox)
|
||||
|
||||
@property (nonatomic) RCTRedBoxButtonPressHandler rct_handler;
|
||||
|
||||
- (void)rct_addBlock:(RCTRedBoxButtonPressHandler)handler forControlEvents:(UIControlEvents)controlEvents;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIButton (RCTRedBox)
|
||||
|
||||
- (RCTRedBoxButtonPressHandler)rct_handler
|
||||
{
|
||||
return objc_getAssociatedObject(self, @selector(rct_handler));
|
||||
}
|
||||
|
||||
- (void)setRct_handler:(RCTRedBoxButtonPressHandler)rct_handler
|
||||
{
|
||||
objc_setAssociatedObject(self, @selector(rct_handler), rct_handler, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)rct_callBlock
|
||||
{
|
||||
if (self.rct_handler) {
|
||||
self.rct_handler();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rct_addBlock:(RCTRedBoxButtonPressHandler)handler forControlEvents:(UIControlEvents)controlEvents
|
||||
{
|
||||
self.rct_handler = handler;
|
||||
[self addTarget:self action:@selector(rct_callBlock) forControlEvents:controlEvents];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@protocol RCTRedBoxWindowActionDelegate <NSObject>
|
||||
|
||||
- (void)redBoxWindow:(RCTRedBoxWindow *)redBoxWindow openStackFrameInEditor:(RCTJSStackFrame *)stackFrame;
|
||||
@@ -54,7 +91,7 @@ BOOL RCTRedBoxGetEnabled() {
|
||||
int _lastErrorCookie;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
- (instancetype)initWithFrame:(CGRect)frame customButtonTitles:(NSArray<NSString *>*)customButtonTitles customButtonHandlers:(NSArray<RCTRedBoxButtonPressHandler> *)customButtonHandlers
|
||||
{
|
||||
_lastErrorCookie = -1;
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
@@ -100,26 +137,32 @@ BOOL RCTRedBoxGetEnabled() {
|
||||
NSString *extraText = @"Extra Info";
|
||||
#endif
|
||||
|
||||
UIButton *dismissButton = [self redBoxButton:dismissText accessibilityIdentifier:@"redbox-dismiss" selector:@selector(dismiss)];
|
||||
UIButton *reloadButton = [self redBoxButton:reloadText accessibilityIdentifier:@"redbox-reload" selector:@selector(reload)];
|
||||
UIButton *copyButton = [self redBoxButton:copyText accessibilityIdentifier:@"redbox-copy" selector:@selector(copyStack)];
|
||||
UIButton *extraButton = [self redBoxButton:extraText accessibilityIdentifier:@"redbox-extra" selector:@selector(showExtraDataViewController)];
|
||||
UIButton *dismissButton = [self redBoxButton:dismissText accessibilityIdentifier:@"redbox-dismiss" selector:@selector(dismiss) block:nil];
|
||||
UIButton *reloadButton = [self redBoxButton:reloadText accessibilityIdentifier:@"redbox-reload" selector:@selector(reload) block:nil];
|
||||
UIButton *copyButton = [self redBoxButton:copyText accessibilityIdentifier:@"redbox-copy" selector:@selector(copyStack) block:nil];
|
||||
UIButton *extraButton = [self redBoxButton:extraText accessibilityIdentifier:@"redbox-extra" selector:@selector(showExtraDataViewController) block:nil];
|
||||
|
||||
CGFloat buttonWidth = self.bounds.size.width / 4;
|
||||
CGFloat buttonWidth = self.bounds.size.width / (4 + [customButtonTitles count]);
|
||||
CGFloat bottomButtonHeight = self.bounds.size.height - buttonHeight - [self bottomSafeViewHeight];
|
||||
|
||||
dismissButton.frame = CGRectMake(0, bottomButtonHeight, buttonWidth, buttonHeight);
|
||||
reloadButton.frame = CGRectMake(buttonWidth, bottomButtonHeight, buttonWidth, buttonHeight);
|
||||
copyButton.frame = CGRectMake(buttonWidth * 2, bottomButtonHeight, buttonWidth, buttonHeight);
|
||||
extraButton.frame = CGRectMake(buttonWidth * 3, bottomButtonHeight, buttonWidth, buttonHeight);
|
||||
|
||||
UIView *topBorder = [[UIView alloc] initWithFrame:CGRectMake(0, bottomButtonHeight + 1, rootView.frame.size.width, 1)];
|
||||
topBorder.backgroundColor = [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
|
||||
|
||||
[rootView addSubview:dismissButton];
|
||||
[rootView addSubview:reloadButton];
|
||||
[rootView addSubview:copyButton];
|
||||
[rootView addSubview:extraButton];
|
||||
|
||||
for (NSUInteger i = 0; i < [customButtonTitles count]; i++) {
|
||||
UIButton *button = [self redBoxButton:customButtonTitles[i] accessibilityIdentifier:@"" selector:nil block:customButtonHandlers[i]];
|
||||
button.frame = CGRectMake(buttonWidth * (4 + i), bottomButtonHeight, buttonWidth, buttonHeight);
|
||||
[rootView addSubview:button];
|
||||
}
|
||||
|
||||
UIView *topBorder = [[UIView alloc] initWithFrame:CGRectMake(0, bottomButtonHeight + 1, rootView.frame.size.width, 1)];
|
||||
topBorder.backgroundColor = [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
|
||||
|
||||
[rootView addSubview:topBorder];
|
||||
|
||||
UIView *bottomSafeView = [UIView new];
|
||||
@@ -131,7 +174,7 @@ BOOL RCTRedBoxGetEnabled() {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIButton *)redBoxButton:(NSString *)title accessibilityIdentifier:(NSString *)accessibilityIdentifier selector:(SEL)selector
|
||||
- (UIButton *)redBoxButton:(NSString *)title accessibilityIdentifier:(NSString *)accessibilityIdentifier selector:(SEL)selector block:(RCTRedBoxButtonPressHandler)block
|
||||
{
|
||||
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
button.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
|
||||
@@ -143,7 +186,11 @@ BOOL RCTRedBoxGetEnabled() {
|
||||
[button setTitle:title forState:UIControlStateNormal];
|
||||
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
[button setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateHighlighted];
|
||||
[button addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
|
||||
if (selector) {
|
||||
[button addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
|
||||
} else if (block) {
|
||||
[button rct_addBlock:block forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
@@ -399,6 +446,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
RCTRedBoxWindow *_window;
|
||||
NSMutableArray<id<RCTErrorCustomizer>> *_errorCustomizers;
|
||||
RCTRedBoxExtraDataViewController *_extraDataViewController;
|
||||
NSMutableArray<NSString *> *_customButtonTitles;
|
||||
NSMutableArray<RCTRedBoxButtonPressHandler> *_customButtonHandlers;
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
@@ -524,7 +573,7 @@ RCT_EXPORT_MODULE()
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if (!self->_window) {
|
||||
self->_window = [[RCTRedBoxWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
self->_window = [[RCTRedBoxWindow alloc] initWithFrame:[UIScreen mainScreen].bounds customButtonTitles:self->_customButtonTitles customButtonHandlers:self->_customButtonHandlers];
|
||||
self->_window.actionDelegate = self;
|
||||
}
|
||||
|
||||
@@ -599,6 +648,17 @@ RCT_EXPORT_METHOD(dismiss)
|
||||
[self dismiss];
|
||||
}
|
||||
|
||||
- (void)addCustomButton:(NSString *)title onPressHandler:(RCTRedBoxButtonPressHandler)handler
|
||||
{
|
||||
if (!_customButtonTitles) {
|
||||
_customButtonTitles = [NSMutableArray new];
|
||||
_customButtonHandlers = [NSMutableArray new];
|
||||
}
|
||||
|
||||
[_customButtonTitles addObject:title];
|
||||
[_customButtonHandlers addObject:handler];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTBridge (RCTRedBox)
|
||||
@@ -632,6 +692,8 @@ RCT_EXPORT_METHOD(dismiss)
|
||||
|
||||
- (void)dismiss {}
|
||||
|
||||
- (void)addCustomButton:(NSString *)title onPressHandler:(RCTRedBoxButtonPressHandler)handler {}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTBridge (RCTRedBox)
|
||||
|
||||
Reference in New Issue
Block a user