diff --git a/Examples/UIExplorer/TextExample.ios.js b/Examples/UIExplorer/TextExample.ios.js index 1574f8a0b..cceca74e6 100644 --- a/Examples/UIExplorer/TextExample.ios.js +++ b/Examples/UIExplorer/TextExample.ios.js @@ -378,6 +378,25 @@ exports.examples = [ ); }, +}, { + title: 'allowFontScaling attribute', + render: function() { + return ( + + + By default, text will respect Text Size accessibility setting on iOS. + It means that all font sizes will be increased or descreased depending on the value of Text Size setting in + {" "}Settings.app - Display & Brightness - Text Size + + + You can disable scaling for your Text component by passing {"\""}allowFontScaling={"{"}false{"}\""} prop. + + + This text will not scale. + + + ); + }, }]; var styles = StyleSheet.create({ diff --git a/Libraries/ART/RCTConvert+ART.m b/Libraries/ART/RCTConvert+ART.m index 7a607a12c..e6bc09286 100644 --- a/Libraries/ART/RCTConvert+ART.m +++ b/Libraries/ART/RCTConvert+ART.m @@ -87,7 +87,7 @@ RCT_ENUM_CONVERTER(CTTextAlignment, (@{ } NSDictionary *fontDict = dict[@"font"]; - CTFontRef font = (__bridge CTFontRef)[self UIFont:nil withFamily:fontDict[@"fontFamily"] size:fontDict[@"fontSize"] weight:fontDict[@"fontWeight"] style:fontDict[@"fontStyle"]]; + CTFontRef font = (__bridge CTFontRef)[self UIFont:nil withFamily:fontDict[@"fontFamily"] size:fontDict[@"fontSize"] weight:fontDict[@"fontWeight"] style:fontDict[@"fontStyle"] scaleMultiplier:1.0]; if (!font) { return frame; } diff --git a/Libraries/Text/RCTShadowRawText.m b/Libraries/Text/RCTShadowRawText.m index e99e1187b..a76cc288b 100644 --- a/Libraries/Text/RCTShadowRawText.m +++ b/Libraries/Text/RCTShadowRawText.m @@ -9,8 +9,32 @@ #import "RCTShadowRawText.h" +#import "RCTUIManager.h" + @implementation RCTShadowRawText +- (instancetype)init +{ + if ((self = [super init])) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(contentSizeMultiplierDidChange:) + name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification + object:nil]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)contentSizeMultiplierDidChange:(NSNotification *)note +{ + [self dirtyLayout]; + [self dirtyText]; +} + - (void)setText:(NSString *)text { if (_text != text) { diff --git a/Libraries/Text/RCTShadowText.h b/Libraries/Text/RCTShadowText.h index fe87e99c1..abb111879 100644 --- a/Libraries/Text/RCTShadowText.h +++ b/Libraries/Text/RCTShadowText.h @@ -30,6 +30,8 @@ extern NSString *const RCTReactTagAttributeName; @property (nonatomic, strong) UIColor *textDecorationColor; @property (nonatomic, assign) NSUnderlineStyle textDecorationStyle; @property (nonatomic, assign) RCTTextDecorationLineType textDecorationLine; +@property (nonatomic, assign) CGFloat fontSizeMultiplier; +@property (nonatomic, assign) BOOL allowFontScaling; - (void)recomputeText; diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m index 621df1ed6..61f1373c1 100644 --- a/Libraries/Text/RCTShadowText.m +++ b/Libraries/Text/RCTShadowText.m @@ -9,6 +9,9 @@ #import "RCTShadowText.h" +#import "RCTAccessibilityManager.h" +#import "RCTUIManager.h" +#import "RCTBridge.h" #import "RCTConvert.h" #import "RCTLog.h" #import "RCTShadowRawText.h" @@ -51,16 +54,31 @@ static css_dim_t RCTMeasure(void *context, float width) _letterSpacing = NAN; _isHighlighted = NO; _textDecorationStyle = NSUnderlineStyleSingle; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(contentSizeMultiplierDidChange:) + name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification + object:nil]; } return self; } +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + - (NSString *)description { NSString *superDescription = super.description; return [[superDescription substringToIndex:superDescription.length - 1] stringByAppendingFormat:@"; text: %@>", [self attributedString].string]; } +- (void)contentSizeMultiplierDidChange:(NSNotification *)note +{ + [self dirtyLayout]; + [self dirtyText]; +} + - (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties { @@ -190,7 +208,9 @@ static css_dim_t RCTMeasure(void *context, float width) [self _addAttribute:NSBackgroundColorAttributeName withValue:self.backgroundColor toAttributedString:attributedString]; } - UIFont *font = [RCTConvert UIFont:nil withFamily:fontFamily size:fontSize weight:fontWeight style:fontStyle]; + UIFont *font = [RCTConvert UIFont:nil withFamily:fontFamily + size:fontSize weight:fontWeight style:fontStyle + scaleMultiplier:(_allowFontScaling && _fontSizeMultiplier > 0.0 ? _fontSizeMultiplier : 1.0)]; [self _addAttribute:NSFontAttributeName withValue:font toAttributedString:attributedString]; [self _addAttribute:NSKernAttributeName withValue:letterSpacing toAttributedString:attributedString]; [self _addAttribute:RCTReactTagAttributeName withValue:self.reactTag toAttributedString:attributedString]; @@ -232,8 +252,9 @@ static css_dim_t RCTMeasure(void *context, float width) [attributedString enumerateAttribute:NSParagraphStyleAttributeName inRange:NSMakeRange(0, [attributedString length]) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { if (value) { NSParagraphStyle *paragraphStyle = (NSParagraphStyle *)value; - if ([paragraphStyle maximumLineHeight] > _lineHeight) { - self.lineHeight = [paragraphStyle maximumLineHeight]; + CGFloat maximumLineHeight = round([paragraphStyle maximumLineHeight] / self.fontSizeMultiplier); + if (maximumLineHeight > self.lineHeight) { + self.lineHeight = maximumLineHeight; } hasParagraphStyle = YES; } @@ -247,8 +268,9 @@ static css_dim_t RCTMeasure(void *context, float width) NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.alignment = _textAlign; paragraphStyle.baseWritingDirection = _writingDirection; - paragraphStyle.minimumLineHeight = _lineHeight; - paragraphStyle.maximumLineHeight = _lineHeight; + CGFloat lineHeight = round(_lineHeight * self.fontSizeMultiplier); + paragraphStyle.minimumLineHeight = lineHeight; + paragraphStyle.maximumLineHeight = lineHeight; [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:(NSRange){0, attributedString.length}]; @@ -321,4 +343,26 @@ RCT_TEXT_PROPERTY(TextDecorationLine, _textDecorationLine, RCTTextDecorationLine RCT_TEXT_PROPERTY(TextDecorationStyle, _textDecorationStyle, NSUnderlineStyle); RCT_TEXT_PROPERTY(WritingDirection, _writingDirection, NSWritingDirection) +- (void)setAllowFontScaling:(BOOL)allowFontScaling +{ + _allowFontScaling = allowFontScaling; + for (RCTShadowView *child in [self reactSubviews]) { + if ([child isKindOfClass:[RCTShadowText class]]) { + [(RCTShadowText *)child setAllowFontScaling:allowFontScaling]; + } + } + [self dirtyText]; +} + +- (void)setFontSizeMultiplier:(CGFloat)fontSizeMultiplier +{ + _fontSizeMultiplier = fontSizeMultiplier; + for (RCTShadowView *child in [self reactSubviews]) { + if ([child isKindOfClass:[RCTShadowText class]]) { + [(RCTShadowText *)child setFontSizeMultiplier:fontSizeMultiplier]; + } + } + [self dirtyText]; +} + @end diff --git a/Libraries/Text/RCTTextManager.m b/Libraries/Text/RCTTextManager.m index b5f959b73..06d52088a 100644 --- a/Libraries/Text/RCTTextManager.m +++ b/Libraries/Text/RCTTextManager.m @@ -9,6 +9,7 @@ #import "RCTTextManager.h" +#import "RCTAccessibilityManager.h" #import "RCTAssert.h" #import "RCTConvert.h" #import "RCTLog.h" @@ -49,6 +50,7 @@ RCT_EXPORT_SHADOW_PROPERTY(textDecorationStyle, NSUnderlineStyle) RCT_EXPORT_SHADOW_PROPERTY(textDecorationColor, UIColor) RCT_EXPORT_SHADOW_PROPERTY(textDecorationLine, RCTTextDecorationLineType) RCT_EXPORT_SHADOW_PROPERTY(writingDirection, NSWritingDirection) +RCT_EXPORT_SHADOW_PROPERTY(allowFontScaling, BOOL) - (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(RCTSparseArray *)shadowViewRegistry { @@ -69,6 +71,7 @@ RCT_EXPORT_SHADOW_PROPERTY(writingDirection, NSWritingDirection) RCTAssert([shadowView isTextDirty], @"Don't process any nodes that don't have dirty text"); if ([shadowView isKindOfClass:[RCTShadowText class]]) { + [(RCTShadowText *)shadowView setFontSizeMultiplier:self.bridge.accessibilityManager.multiplier]; [(RCTShadowText *)shadowView recomputeText]; } else if ([shadowView isKindOfClass:[RCTShadowRawText class]]) { RCTLogError(@"Raw text cannot be used outside of a tag. Not rendering string: '%@'", diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index cc1b93d4c..3d98ff56a 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -30,6 +30,7 @@ var viewConfig = { validAttributes: merge(ReactNativeViewAttributes.UIView, { isHighlighted: true, numberOfLines: true, + allowFontScaling: true, }), uiViewClassName: 'RCTText', }; @@ -99,15 +100,25 @@ var Text = React.createClass({ * Used to locate this view in end-to-end tests. */ testID: React.PropTypes.string, + /** + * Specifies should fonts scale to respect Text Size accessibility setting on iOS. + */ + allowFontScaling: React.PropTypes.bool, }, viewConfig: viewConfig, - getInitialState: function() { + getInitialState: function(): Object { return merge(this.touchableGetInitialState(), { isHighlighted: false, }); }, + + getDefaultProps: function(): Object { + return { + allowFontScaling: true, + }; + }, onStartShouldSetResponder: function(): bool { var shouldSetFromProps = this.props.onStartShouldSetResponder && diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index 50b677dd9..6f23d1d7a 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -91,7 +91,8 @@ typedef NSURL RCTFileURL; + (UIFont *)UIFont:(UIFont *)font withStyle:(id)json; + (UIFont *)UIFont:(UIFont *)font withFamily:(id)json; + (UIFont *)UIFont:(UIFont *)font withFamily:(id)family - size:(id)size weight:(id)weight style:(id)style; + size:(id)size weight:(id)weight style:(id)style + scaleMultiplier:(CGFloat)scaleMultiplier; typedef NSArray NSStringArray; + (NSStringArray *)NSStringArray:(id)json; diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 4d3355eb9..8e6b7476c 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -779,31 +779,33 @@ static BOOL RCTFontIsCondensed(UIFont *font) withFamily:json[@"fontFamily"] size:json[@"fontSize"] weight:json[@"fontWeight"] - style:json[@"fontStyle"]]; + style:json[@"fontStyle"] + scaleMultiplier:1.0f]; } + (UIFont *)UIFont:(UIFont *)font withSize:(id)json { - return [self UIFont:font withFamily:nil size:json weight:nil style:nil]; + return [self UIFont:font withFamily:nil size:json weight:nil style:nil scaleMultiplier:1.0]; } + (UIFont *)UIFont:(UIFont *)font withWeight:(id)json { - return [self UIFont:font withFamily:nil size:nil weight:json style:nil]; + return [self UIFont:font withFamily:nil size:nil weight:json style:nil scaleMultiplier:1.0]; } + (UIFont *)UIFont:(UIFont *)font withStyle:(id)json { - return [self UIFont:font withFamily:nil size:nil weight:nil style:json]; + return [self UIFont:font withFamily:nil size:nil weight:nil style:json scaleMultiplier:1.0]; } + (UIFont *)UIFont:(UIFont *)font withFamily:(id)json { - return [self UIFont:font withFamily:json size:nil weight:nil style:nil]; + return [self UIFont:font withFamily:json size:nil weight:nil style:nil scaleMultiplier:1.0]; } + (UIFont *)UIFont:(UIFont *)font withFamily:(id)family size:(id)size weight:(id)weight style:(id)style + scaleMultiplier:(CGFloat)scaleMultiplier { // Defaults NSString *const RCTDefaultFontFamily = @"System"; @@ -828,6 +830,9 @@ static BOOL RCTFontIsCondensed(UIFont *font) // Get font attributes fontSize = [self CGFloat:size] ?: fontSize; + if (scaleMultiplier > 0.0 && scaleMultiplier != 1.0) { + fontSize = round(fontSize * scaleMultiplier); + } familyName = [self NSString:family] ?: familyName; isItalic = style ? [self RCTFontStyle:style] : isItalic; fontWeight = weight ? [self RCTFontWeight:weight] : fontWeight; diff --git a/React/Modules/RCTAccessibilityManager.h b/React/Modules/RCTAccessibilityManager.h new file mode 100644 index 000000000..03d22f945 --- /dev/null +++ b/React/Modules/RCTAccessibilityManager.h @@ -0,0 +1,27 @@ +/** + * 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 + +#import "RCTBridgeModule.h" +#import "RCTBridge.h" + +extern NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification; // posted when multiplier is changed + +@interface RCTAccessibilityManager : NSObject + +@property (nonatomic, readonly) CGFloat multiplier; + +@end + +@interface RCTBridge (RCTAccessibilityManager) + +@property (nonatomic, readonly) RCTAccessibilityManager *accessibilityManager; + +@end diff --git a/React/Modules/RCTAccessibilityManager.m b/React/Modules/RCTAccessibilityManager.m new file mode 100644 index 000000000..9271b1e3d --- /dev/null +++ b/React/Modules/RCTAccessibilityManager.m @@ -0,0 +1,144 @@ +/** + * 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 diff --git a/React/Modules/RCTUIManager.h b/React/Modules/RCTUIManager.h index 79ce01463..d1f9d5f15 100644 --- a/React/Modules/RCTUIManager.h +++ b/React/Modules/RCTUIManager.h @@ -14,6 +14,12 @@ #import "RCTInvalidating.h" #import "RCTViewManager.h" +/** + * Posted right before re-render happens. This is a chance for views to invalidate their state so + * next render cycle will pick up updated views and layout appropriately. + */ +extern NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification; + @protocol RCTScrollableProtocol; /** diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index d1d64ee36..6eb13fa0d 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -14,6 +14,7 @@ #import #import "Layout.h" +#import "RCTAccessibilityManager.h" #import "RCTAnimationType.h" #import "RCTAssert.h" #import "RCTBridge.h" @@ -42,6 +43,8 @@ static void RCTTraverseViewNodes(id view, react_view_node_b } } +NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification = @"RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification"; + @interface RCTAnimation : NSObject @property (nonatomic, readonly) NSTimeInterval duration; @@ -269,10 +272,33 @@ static NSDictionary *RCTViewConfigForModule(Class managerClass) _rootViewTags = [[NSMutableSet alloc] init]; _bridgeTransactionListeners = [[NSMutableSet alloc] init]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(didReceiveNewContentSizeMultiplier) + name:RCTAccessibilityManagerDidUpdateMultiplierNotification + object:nil]; } return self; } +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)didReceiveNewContentSizeMultiplier +{ + __weak RCTUIManager *weakSelf = self; + dispatch_async(self.methodQueue, ^{ + __weak RCTUIManager *strongSelf = weakSelf; + if (strongSelf) { + [[NSNotificationCenter defaultCenter] postNotificationName:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification + object:strongSelf]; + [strongSelf batchDidComplete]; + } + }); +} + - (BOOL)isValid { return _viewRegistry != nil; diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 94968a214..692e9742b 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -79,6 +79,7 @@ 83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; }; 83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; }; 83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; }; + E9B20B7B1B500126007A2DA7 /* RCTAccessibilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -253,6 +254,8 @@ 83CBBACA1A6023D300E9B192 /* RCTConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTConvert.h; sourceTree = ""; }; 83CBBACB1A6023D300E9B192 /* RCTConvert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert.m; sourceTree = ""; }; E3BBC8EB1ADE6F47001BBD81 /* RCTTextDecorationLineType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTTextDecorationLineType.h; sourceTree = ""; }; + E9B20B791B500126007A2DA7 /* RCTAccessibilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAccessibilityManager.h; sourceTree = ""; }; + E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAccessibilityManager.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -289,6 +292,8 @@ 13B07FE01A69315300A75B9A /* Modules */ = { isa = PBXGroup; children = ( + E9B20B791B500126007A2DA7 /* RCTAccessibilityManager.h */, + E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */, 13B07FE71A69327A00A75B9A /* RCTAlertManager.h */, 13B07FE81A69327A00A75B9A /* RCTAlertManager.m */, 1372B7081AB030C200659ED6 /* RCTAppState.h */, @@ -607,6 +612,7 @@ 137327EA1AA5CF210034F82E /* RCTTabBarManager.m in Sources */, 13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */, 13B080051A6947C200A75B9A /* RCTScrollView.m in Sources */, + E9B20B7B1B500126007A2DA7 /* RCTAccessibilityManager.m in Sources */, 13B07FF21A69327A00A75B9A /* RCTTiming.m in Sources */, 1372B70A1AB030C200659ED6 /* RCTAppState.m in Sources */, 134FCB3D1A6E7F0800051CC8 /* RCTContextExecutor.m in Sources */,