mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-11 09:11:14 +08:00
Summary: Dynamic Text Sizes for Text component. Text gains new prop - allowFontScaling (true by default). There is also AccessibilityManager module that allows you to tune multipliers per each content size category, but predefined multipliers are there. This could potentially break some apps so please test carefully.
145 lines
4.9 KiB
Objective-C
145 lines
4.9 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import "RCTAccessibilityManager.h"
|
|
|
|
#import "RCTLog.h"
|
|
|
|
NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification = @"RCTAccessibilityManagerDidUpdateMultiplierNotification";
|
|
|
|
@interface RCTAccessibilityManager ()
|
|
|
|
@property (nonatomic, copy) NSDictionary *multipliers;
|
|
@property (nonatomic, copy) NSString *contentSizeCategory;
|
|
@property (nonatomic, assign) CGFloat multiplier;
|
|
|
|
@end
|
|
|
|
@implementation RCTAccessibilityManager
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
+ (NSDictionary *)JSToUIKitMap
|
|
{
|
|
static NSDictionary *map = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
map = @{@"extraSmall": UIContentSizeCategoryExtraSmall,
|
|
@"small": UIContentSizeCategorySmall,
|
|
@"medium": UIContentSizeCategoryMedium,
|
|
@"large": UIContentSizeCategoryLarge,
|
|
@"extraLarge": UIContentSizeCategoryExtraLarge,
|
|
@"extraExtraLarge": UIContentSizeCategoryExtraExtraLarge,
|
|
@"extraExtraExtraLarge": UIContentSizeCategoryExtraExtraExtraLarge,
|
|
@"accessibilityMedium": UIContentSizeCategoryAccessibilityMedium,
|
|
@"accessibilityLarge": UIContentSizeCategoryAccessibilityLarge,
|
|
@"accessibilityExtraLarge": UIContentSizeCategoryAccessibilityExtraLarge,
|
|
@"accessibilityExtraExtraLarge": UIContentSizeCategoryAccessibilityExtraExtraLarge,
|
|
@"accessibilityExtraExtraExtraLarge": UIContentSizeCategoryAccessibilityExtraExtraExtraLarge};
|
|
});
|
|
return map;
|
|
}
|
|
|
|
+ (NSString *)UIKitCategoryFromJSCategory:(NSString *)JSCategory
|
|
{
|
|
return self.JSToUIKitMap[JSCategory];
|
|
}
|
|
|
|
- (instancetype)init
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(didReceiveNewContentSizeCategory:)
|
|
name:UIContentSizeCategoryDidChangeNotification
|
|
object:[UIApplication sharedApplication]];
|
|
self.contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
}
|
|
|
|
- (void)didReceiveNewContentSizeCategory:(NSNotification *)note
|
|
{
|
|
self.contentSizeCategory = note.userInfo[UIContentSizeCategoryNewValueKey];
|
|
}
|
|
|
|
- (void)setContentSizeCategory:(NSString *)contentSizeCategory
|
|
{
|
|
if (_contentSizeCategory != contentSizeCategory) {
|
|
_contentSizeCategory = [contentSizeCategory copy];
|
|
self.multiplier = [self multiplierForContentSizeCategory:_contentSizeCategory];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTAccessibilityManagerDidUpdateMultiplierNotification object:self];
|
|
}
|
|
}
|
|
|
|
- (CGFloat)multiplierForContentSizeCategory:(NSString *)category
|
|
{
|
|
NSNumber *m = self.multipliers[category];
|
|
if (m.doubleValue <= 0.0) {
|
|
RCTLogError(@"Can't determinte multiplier for category %@. Using 1.0.", category);
|
|
m = @1.0;
|
|
}
|
|
return m.doubleValue;
|
|
}
|
|
|
|
- (NSDictionary *)multipliers
|
|
{
|
|
if (_multipliers == nil) {
|
|
_multipliers = @{UIContentSizeCategoryExtraSmall: @0.823,
|
|
UIContentSizeCategorySmall: @0.882,
|
|
UIContentSizeCategoryMedium: @0.941,
|
|
UIContentSizeCategoryLarge: @1.0,
|
|
UIContentSizeCategoryExtraLarge: @1.118,
|
|
UIContentSizeCategoryExtraExtraLarge: @1.235,
|
|
UIContentSizeCategoryExtraExtraExtraLarge: @1.353,
|
|
UIContentSizeCategoryAccessibilityMedium: @1.786,
|
|
UIContentSizeCategoryAccessibilityLarge: @2.143,
|
|
UIContentSizeCategoryAccessibilityExtraLarge: @2.643,
|
|
UIContentSizeCategoryAccessibilityExtraExtraLarge: @3.143,
|
|
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @3.571};
|
|
}
|
|
return _multipliers;
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(setAccessibilityContentSizeMultipliers:(NSDictionary *)JSMultipliers)
|
|
{
|
|
NSMutableDictionary *multipliers = [[NSMutableDictionary alloc] init];
|
|
for (NSString *__nonnull JSCategory in JSMultipliers) {
|
|
NSNumber *m = JSMultipliers[JSCategory];
|
|
NSString *UIKitCategory = [self.class UIKitCategoryFromJSCategory:JSCategory];
|
|
multipliers[UIKitCategory] = m;
|
|
}
|
|
self.multipliers = multipliers;
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getMultiplier:(RCTResponseSenderBlock)callback)
|
|
{
|
|
if (callback) {
|
|
callback(@[ @(self.multiplier) ]);
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation RCTBridge (RCTAccessibilityManager)
|
|
|
|
- (RCTAccessibilityManager *)accessibilityManager
|
|
{
|
|
return self.modules[RCTBridgeModuleNameForClass([RCTAccessibilityManager class])];
|
|
}
|
|
|
|
@end
|