Files
react-native/React/CoreModules/RCTAppearance.mm
T
Héctor RamosandFacebook Github Bot 63fa3f21c5 Add Appearance native module
Summary:
Implements the Appearance native module as discussed in https://github.com/react-native-community/discussions-and-proposals/issues/126.

The purpose of the Appearance native module is to expose the user's appearance preferences. It provides a basic get() API that returns the user's preferred color scheme on iOS 13 devices, also known as Dark Mode. It also provides the ability to subscribe to events whenever an appearance preference changes.

The name, "Appearance", was chosen purposefully to allow for future expansion to cover other appearance preferences such as reduced motion, reduced transparency, or high contrast modes.

Changelog:

[iOS] [Added] - The Appearance native module can be used to prepare your app for Dark Mode on iOS 13.

Reviewed By: yungsters

Differential Revision: D16699954

fbshipit-source-id: 03b4cc5d2a1a69f31f3a6d9bece23f6867b774ea
2019-08-30 17:07:57 -07:00

108 lines
2.7 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 "RCTAppearance.h"
#import <FBReactNativeSpec/FBReactNativeSpec.h>
#import <React/RCTEventEmitter.h>
#import "CoreModulesPlugins.h"
using namespace facebook::react;
NSString *const RCTAppearanceColorSchemeLight = @"light";
NSString *const RCTAppearanceColorSchemeDark = @"dark";
static NSString *RCTColorSchemePreference(UITraitCollection *traitCollection)
{
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
if (@available(iOS 13.0, *)) {
static NSDictionary *appearances;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
appearances = @{
@(UIUserInterfaceStyleLight): RCTAppearanceColorSchemeLight,
@(UIUserInterfaceStyleDark): RCTAppearanceColorSchemeDark
};
});
traitCollection = traitCollection ?: [UITraitCollection currentTraitCollection];
return appearances[@(traitCollection.userInterfaceStyle)] ?: nil;
}
#endif
return nil;
}
@interface RCTAppearance () <NativeAppearanceSpec>
@end
@implementation RCTAppearance
RCT_EXPORT_MODULE(Appearance)
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
- (std::shared_ptr<TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<JSCallInvoker>)jsInvoker
{
return std::make_shared<NativeAppearanceSpecJSI>(self, jsInvoker);
}
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getColorScheme)
{
return RCTColorSchemePreference(nil);
}
- (void)appearanceChanged:(NSNotification *)notification
{
NSDictionary *userInfo = [notification userInfo];
UITraitCollection *traitCollection = nil;
if (userInfo) {
traitCollection = userInfo[@"traitCollection"];
}
[self sendEventWithName:@"appearanceChanged" body:@{@"colorScheme": RCTColorSchemePreference(traitCollection)}];
}
#pragma mark - RCTEventEmitter
- (NSArray<NSString *> *)supportedEvents
{
return @[@"appearanceChanged"];
}
- (void)startObserving
{
if (@available(iOS 13.0, *)) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appearanceChanged:)
name:RCTUserInterfaceStyleDidChangeNotification
object:nil];
}
}
- (void)stopObserving
{
if (@available(iOS 13.0, *)) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
@end
Class RCTAppearanceCls(void) {
return RCTAppearance.class;
}