mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
0a9cc34dd8
Summary: Support to override actionsheet and share interface style to match your app. For example, when your app has it's own theming you want to match the stying on actionsheet and the share menu. ## Changelog [iOS] [Added] - Added userInterfaceStyle for ActionSheetIOS and Share to override user interface style on IOS 13 Pull Request resolved: https://github.com/facebook/react-native/pull/26401 Test Plan: Set dark style  Set light style  Differential Revision: D17314080 Pulled By: hramos fbshipit-source-id: f84278ca99ba20347d17e27295f661d6690fa68c
209 lines
6.4 KiB
Plaintext
209 lines
6.4 KiB
Plaintext
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#import <React/RCTDevLoadingView.h>
|
|
|
|
#import <QuartzCore/QuartzCore.h>
|
|
|
|
#import <React/RCTBridge.h>
|
|
#import <React/RCTConvert.h>
|
|
#import <React/RCTDefines.h>
|
|
#import <React/RCTDevLoadingViewSetEnabled.h>
|
|
#import <React/RCTModalHostViewController.h>
|
|
#import <React/RCTUtils.h>
|
|
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
|
|
|
#import "CoreModulesPlugins.h"
|
|
|
|
using namespace facebook::react;
|
|
|
|
@interface RCTDevLoadingView () <NativeDevLoadingViewSpec>
|
|
@end
|
|
|
|
#if RCT_DEV | RCT_ENABLE_LOADING_VIEW
|
|
|
|
@implementation RCTDevLoadingView
|
|
{
|
|
UIWindow *_window;
|
|
UILabel *_label;
|
|
NSDate *_showDate;
|
|
}
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
+ (void)setEnabled:(BOOL)enabled
|
|
{
|
|
RCTDevLoadingViewSetEnabled(enabled);
|
|
}
|
|
|
|
+ (BOOL)requiresMainQueueSetup
|
|
{
|
|
return YES;
|
|
}
|
|
|
|
- (void)setBridge:(RCTBridge *)bridge
|
|
{
|
|
_bridge = bridge;
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(hide)
|
|
name:RCTJavaScriptDidLoadNotification
|
|
object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(hide)
|
|
name:RCTJavaScriptDidFailToLoadNotification
|
|
object:nil];
|
|
|
|
if (bridge.loading) {
|
|
[self showWithURL:bridge.bundleURL];
|
|
}
|
|
}
|
|
|
|
-(void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(UIColor *)backgroundColor
|
|
{
|
|
if (!RCTDevLoadingViewGetEnabled()) {
|
|
return;
|
|
}
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
self->_showDate = [NSDate date];
|
|
if (!self->_window && !RCTRunningInTestEnvironment()) {
|
|
CGSize screenSize = [UIScreen mainScreen].bounds.size;
|
|
|
|
if (@available(iOS 11.0, *)) {
|
|
UIWindow *window = RCTSharedApplication().keyWindow;
|
|
self->_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, window.safeAreaInsets.top + 30)];
|
|
self->_label = [[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top, screenSize.width, 30)];
|
|
} else {
|
|
self->_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, 22)];
|
|
self->_label = [[UILabel alloc] initWithFrame:self->_window.bounds];
|
|
}
|
|
[self->_window addSubview:self->_label];
|
|
#if TARGET_OS_TV
|
|
self->_window.windowLevel = UIWindowLevelNormal + 1;
|
|
#else
|
|
self->_window.windowLevel = UIWindowLevelStatusBar + 1;
|
|
#endif
|
|
// 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;
|
|
}
|
|
|
|
self->_label.text = message;
|
|
self->_label.textColor = color;
|
|
self->_window.backgroundColor = backgroundColor;
|
|
self->_window.hidden = NO;
|
|
|
|
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
|
|
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
|
if (@available(iOS 13.0, *)) {
|
|
UIWindowScene *scene = (UIWindowScene *)RCTSharedApplication().connectedScenes.anyObject;
|
|
self->_window.windowScene = scene;
|
|
}
|
|
#endif
|
|
});
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(showMessage:(NSString *)message withColor:(NSNumber *)color withBackgroundColor:(NSNumber *)backgroundColor)
|
|
{
|
|
[self showMessage:message color:[RCTConvert UIColor:color] backgroundColor:[RCTConvert UIColor:backgroundColor]];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(hide)
|
|
{
|
|
if (!RCTDevLoadingViewGetEnabled()) {
|
|
return;
|
|
}
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
const NSTimeInterval MIN_PRESENTED_TIME = 0.6;
|
|
NSTimeInterval presentedTime = [[NSDate date] timeIntervalSinceDate:self->_showDate];
|
|
NSTimeInterval delay = MAX(0, MIN_PRESENTED_TIME - presentedTime);
|
|
CGRect windowFrame = self->_window.frame;
|
|
[UIView animateWithDuration:0.25
|
|
delay:delay
|
|
options:0
|
|
animations:^{
|
|
self->_window.frame = CGRectOffset(windowFrame, 0, -windowFrame.size.height);
|
|
} completion:^(__unused BOOL finished) {
|
|
self->_window.frame = windowFrame;
|
|
self->_window.hidden = YES;
|
|
self->_window = nil;
|
|
}];
|
|
});
|
|
}
|
|
|
|
- (void)showWithURL:(NSURL *)URL
|
|
{
|
|
UIColor *color;
|
|
UIColor *backgroundColor;
|
|
NSString *message;
|
|
if (URL.fileURL) {
|
|
// If dev mode is not enabled, we don't want to show this kind of notification
|
|
#if !RCT_DEV
|
|
return;
|
|
#endif
|
|
color = [UIColor whiteColor];
|
|
backgroundColor = [UIColor blackColor];
|
|
message = [NSString stringWithFormat:@"Connect to %@ to develop JavaScript.", RCT_PACKAGER_NAME];
|
|
} else {
|
|
color = [UIColor whiteColor];
|
|
backgroundColor = [UIColor colorWithHue:1./3 saturation:1 brightness:.35 alpha:1];
|
|
message = [NSString stringWithFormat:@"Loading from %@:%@...", URL.host, URL.port];
|
|
}
|
|
|
|
[self showMessage:message
|
|
color:color
|
|
backgroundColor:backgroundColor];
|
|
}
|
|
|
|
- (void)updateProgress:(RCTLoadingProgress *)progress
|
|
{
|
|
if (!progress) {
|
|
return;
|
|
}
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
self->_label.text = [progress description];
|
|
});
|
|
}
|
|
|
|
- (std::shared_ptr<TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
|
|
{
|
|
return std::make_shared<NativeDevLoadingViewSpecJSI>(self, jsInvoker);
|
|
}
|
|
|
|
@end
|
|
|
|
#else
|
|
|
|
@implementation RCTDevLoadingView
|
|
|
|
+ (NSString *)moduleName { return nil; }
|
|
+ (void)setEnabled:(BOOL)enabled { }
|
|
- (void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(UIColor *)backgroundColor { }
|
|
- (void)showMessage:(NSString *)message withColor:(NSNumber *)color withBackgroundColor:(NSNumber *)backgroundColor{ }
|
|
- (void)showWithURL:(NSURL *)URL { }
|
|
- (void)updateProgress:(RCTLoadingProgress *)progress { }
|
|
- (void)hide { }
|
|
- (std::shared_ptr<TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<CallInvoker>)jsInvoker
|
|
{
|
|
return std::make_shared<NativeDevLoadingViewSpecJSI>(self, jsInvoker);
|
|
}
|
|
|
|
@end
|
|
|
|
#endif
|
|
|
|
Class RCTDevLoadingViewCls(void) {
|
|
return RCTDevLoadingView.class;
|
|
}
|