Skip to content

Commit

Permalink
Font weight option support for iOS (#5490)
Browse files Browse the repository at this point in the history
* Add fontWeight support on iOS

* Add tests

* Fix tests
  • Loading branch information
yogevbd committed Sep 16, 2019
1 parent 3c6314d commit f283e15
Show file tree
Hide file tree
Showing 21 changed files with 197 additions and 86 deletions.
6 changes: 5 additions & 1 deletion docs/docs/styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Navigation.mergeOptions(this.props.componentId, {
fontSize: 14,
color: 'red',
fontFamily: 'Helvetica',
fontWeight: 'regular', // Available on iOS only, will ignore fontFamily style and use the iOS system fonts instead. Supported weights are: 'regular', 'bold', 'thin', 'ultraLight', 'light', 'medium', 'semibold', 'heavy' and 'black'.
component: {
name: 'example.CustomTopBarTitle',
alignment: 'center'
Expand All @@ -92,6 +93,7 @@ Navigation.mergeOptions(this.props.componentId, {
fontSize: 14,
color: 'red',
fontFamily: 'Helvetica',
fontWeight: 'regular', // Available on iOS only, will ignore fontFamily style and use the iOS system fonts instead. Supported weights are: 'regular', 'bold', 'thin', 'ultraLight', 'light', 'medium', 'semibold', 'heavy' and 'black'.
alignment: 'center'
},
backButton: {
Expand Down Expand Up @@ -130,6 +132,7 @@ Navigation.mergeOptions(this.props.componentId, {
textColor: 'red',
selectedTextColor: 'blue',
fontFamily: 'Helvetica',
fontWeight: 'regular', // Available on iOS only, will ignore fontFamily style and use the iOS system fonts instead. Supported weights are: 'regular', 'bold', 'thin', 'ultraLight', 'light', 'medium', 'semibold', 'heavy' and 'black'.
fontSize: 10
},
sideMenu: {
Expand Down Expand Up @@ -194,7 +197,8 @@ Navigation.mergeOptions(this.props.componentId, {
visible: true,
fontSize: 30,
color: 'red',
fontFamily: 'Helvetica'
fontFamily: 'Helvetica',
fontWeight: 'regular' // Available on iOS only, will ignore fontFamily style and use the iOS system fonts instead. Supported weights are: 'regular', 'bold', 'thin', 'ultraLight', 'light', 'medium', 'semibold', 'heavy' and 'black'.
},
},
sideMenu: {
Expand Down
3 changes: 3 additions & 0 deletions docs/docs/topBar-buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ The following options can be used to customise buttons.
color: 'red',
disabledColor: 'black',
testID: 'buttonOneTestID',
fontFamily: 'Helvetica',
fontSize: 10
fontWeight: 'regular', // Available on iOS only, will ignore fontFamily style and use the iOS system fonts instead. Supported weights are: 'regular', 'bold', 'thin', 'ultraLight', 'light', 'medium', 'semibold', 'heavy' and 'black'.
// Android only
showAsAction: 'ifRoom', // See below for details.
// iOS only
Expand Down
21 changes: 21 additions & 0 deletions lib/ios/RCTConvert+UIFontWeight.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#import <React/RCTConvert.h>

@interface RCTConvert (UIFontWeight)

@end

@implementation RCTConvert (UIFontWeight)

RCT_ENUM_CONVERTER(UIFontWeight,
(@{@"ultraLight": @(UIFontWeightUltraLight),
@"thin": @(UIFontWeightThin),
@"light": @(UIFontWeightLight),
@"regular": @(UIFontWeightRegular),
@"medium": @(UIFontWeightMedium),
@"semibold": @(UIFontWeightSemibold),
@"bold": @(UIFontWeightBold),
@"heavy": @(UIFontWeightHeavy),
@"black": @(UIFontWeightBlack)
}), UIFontWeightRegular, floatValue)

@end
1 change: 1 addition & 0 deletions lib/ios/RNNBottomTabOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@property(nonatomic, strong) Color *badgeColor;
@property(nonatomic, strong) DotIndicatorOptions *dotIndicator;
@property(nonatomic, strong) Text *fontFamily;
@property(nonatomic, strong) Text *fontWeight;
@property(nonatomic, strong) Text *testID;
@property(nonatomic, strong) Image *icon;
@property(nonatomic, strong) Image *selectedIcon;
Expand Down
1 change: 1 addition & 0 deletions lib/ios/RNNBottomTabOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
self.badge = [TextParser parse:dict key:@"badge"];
self.badgeColor = [ColorParser parse:dict key:@"badgeColor"];
self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
self.fontWeight = [TextParser parse:dict key:@"fontWeight"];
self.testID = [TextParser parse:dict key:@"testID"];

self.dotIndicator = [DotIndicatorParser parse:dict];
Expand Down
6 changes: 5 additions & 1 deletion lib/ios/RNNFontAttributesCreator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

@interface RNNFontAttributesCreator : NSObject

+ (NSDictionary *)createFontAttributesWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize color:(UIColor *)color;
+ (NSDictionary *)createWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize defaultFontSize:(NSNumber *)defaultFontSize fontWeight:(NSString *)fontWeight color:(UIColor *)color defaultColor:(UIColor *)defaultColor;

+ (NSDictionary *)createWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize fontWeight:(NSString *)fontWeight color:(UIColor *)color;

+ (NSDictionary *)createWithDictionary:(NSDictionary *)attributesDictionary fontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize defaultFontSize:(NSNumber *)defaultFontSize fontWeight:(NSString *)fontWeight color:(UIColor *)color defaultColor:(UIColor *)defaultColor;

@end
34 changes: 24 additions & 10 deletions lib/ios/RNNFontAttributesCreator.m
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
#import "RNNFontAttributesCreator.h"
#import "RCTConvert+UIFontWeight.h"

@implementation RNNFontAttributesCreator

+ (NSDictionary *)createFontAttributesWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize color:(UIColor *)color {
+ (NSDictionary *)createWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize defaultFontSize:(NSNumber *)defaultFontSize fontWeight:(NSString *)fontWeight color:(UIColor *)color defaultColor:(UIColor *)defaultColor {
NSMutableDictionary* titleTextAttributes = [NSMutableDictionary new];
if (fontFamily || fontSize || color) {
return [self createWithDictionary:titleTextAttributes fontFamily:fontFamily fontSize:fontSize defaultFontSize:defaultFontSize fontWeight:fontWeight color:color defaultColor:defaultColor];
}

+ (NSDictionary *)createWithFontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize fontWeight:(NSString *)fontWeight color:(UIColor *)color {
NSMutableDictionary* titleTextAttributes = [NSMutableDictionary new];
return [self createWithDictionary:titleTextAttributes fontFamily:fontFamily fontSize:fontSize fontWeight:fontWeight color:color];
}

+ (NSDictionary *)createWithDictionary:(NSDictionary *)attributesDictionary fontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize defaultFontSize:(NSNumber *)defaultFontSize fontWeight:(NSString *)fontWeight color:(UIColor *)color defaultColor:(UIColor *)defaultColor {
return [self createWithDictionary:attributesDictionary fontFamily:fontFamily fontSize:fontSize ?: defaultFontSize fontWeight:fontWeight color:color ?: defaultColor];
}

+ (NSDictionary *)createWithDictionary:(NSDictionary *)attributesDictionary fontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize fontWeight:(NSString *)fontWeight color:(UIColor *)color {
NSMutableDictionary* titleTextAttributes = [NSMutableDictionary dictionaryWithDictionary:attributesDictionary];
if (fontFamily || fontSize || color || fontWeight) {
CGFloat resolvedFontSize = fontSize ? fontSize.floatValue : 17;
if (color) {
titleTextAttributes[NSForegroundColorAttributeName] = color;
}
if (fontFamily){
if (fontSize) {
titleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:fontFamily size:[fontSize floatValue]];
} else {
titleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:fontFamily size:17];
}
} else if (fontSize) {
titleTextAttributes[NSFontAttributeName] = [UIFont systemFontOfSize:[fontSize floatValue]];
if (fontWeight) {
titleTextAttributes[NSFontAttributeName] = [UIFont systemFontOfSize:resolvedFontSize weight:[RCTConvert UIFontWeight:fontWeight]];
} else if (fontFamily){
titleTextAttributes[NSFontAttributeName] = [UIFont fontWithName:fontFamily size:resolvedFontSize];
} else {
titleTextAttributes[NSFontAttributeName] = [UIFont systemFontOfSize:resolvedFontSize];
}
}

Expand Down
1 change: 1 addition & 0 deletions lib/ios/RNNLargeTitleOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
@property (nonatomic, strong) Bool* visible;
@property (nonatomic, strong) Color* color;
@property (nonatomic, strong) Text* fontFamily;
@property (nonatomic, strong) Text* fontWeight;

@end
1 change: 1 addition & 0 deletions lib/ios/RNNLargeTitleOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
self.visible = [BoolParser parse:dict key:@"visible"];
self.color = [ColorParser parse:dict key:@"color"];
self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
self.fontWeight = [TextParser parse:dict key:@"fontWeight"];

return self;
}
Expand Down
36 changes: 4 additions & 32 deletions lib/ios/RNNNavigationButtons.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#import "RNNRootViewController.h"
#import "UIImage+insets.h"
#import "UIViewController+LayoutProtocol.h"
#import "RNNFontAttributesCreator.h"

@interface RNNNavigationButtons()

Expand Down Expand Up @@ -126,8 +127,8 @@ -(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNBu
BOOL enabledBool = enabled ? [enabled boolValue] : YES;
[barButtonItem setEnabled:enabledBool];

NSMutableDictionary* textAttributes = [[NSMutableDictionary alloc] init];
NSMutableDictionary* disabledTextAttributes = [[NSMutableDictionary alloc] init];
NSMutableDictionary* textAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]];
NSMutableDictionary* disabledTextAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]];

if (!enabledBool && disabledColor) {
color = disabledColor;
Expand All @@ -139,18 +140,7 @@ -(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNBu
[barButtonItem setImage:[[iconImage withTintColor:color] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
barButtonItem.tintColor = color;
}

NSNumber* fontSize = [self fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:nil]];
NSString* fontFamily = [self fontFamily:dictionary[@"fontFamily"] defaultFontFamily:[defaultStyle.fontFamily getWithDefaultValue:nil]];
UIFont *font = nil;
if (fontFamily) {
font = [UIFont fontWithName:fontFamily size:[fontSize floatValue]];
} else {
font = [UIFont systemFontOfSize:[fontSize floatValue]];
}
[textAttributes setObject:font forKey:NSFontAttributeName];
[disabledTextAttributes setObject:font forKey:NSFontAttributeName];


[barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateNormal];
[barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateHighlighted];
[barButtonItem setTitleTextAttributes:disabledTextAttributes forState:UIControlStateDisabled];
Expand All @@ -174,24 +164,6 @@ - (UIColor *)color:(UIColor *)color defaultColor:(UIColor *)defaultColor {
return nil;
}

- (NSNumber *)fontSize:(NSNumber *)fontSize defaultFontSize:(NSNumber *)defaultFontSize {
if (fontSize) {
return fontSize;
} else if (defaultFontSize) {
return defaultFontSize;
}

return @(17);
}

- (NSString *)fontFamily:(NSString *)fontFamily defaultFontFamily:(NSString *)defaultFontFamily {
if (fontFamily) {
return fontFamily;
} else {
return defaultFontFamily;
}
}

- (id)getValue:(id)value withDefault:(id)defaultValue {
return value ? value : defaultValue;
}
Expand Down
1 change: 1 addition & 0 deletions lib/ios/RNNSubtitleOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@property (nonatomic, strong) Number* fontSize;
@property (nonatomic, strong) Color* color;
@property (nonatomic, strong) Text* fontFamily;
@property (nonatomic, strong) Text* fontWeight;
@property (nonatomic, strong) Text* alignment;

@end
1 change: 1 addition & 0 deletions lib/ios/RNNSubtitleOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
self.alignment = [TextParser parse:dict key:@"alignment"];
self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
self.fontSize = [NumberParser parse:dict key:@"fontSize"];
self.fontWeight = [TextParser parse:dict key:@"fontWeight"];
self.color = [ColorParser parse:dict key:@"color"];

return self;
Expand Down
39 changes: 5 additions & 34 deletions lib/ios/RNNTabBarItemCreator.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import "RNNTabBarItemCreator.h"
#import "UIImage+tint.h"
#import "RNNFontAttributesCreator.h"

@implementation RNNTabBarItemCreator

Expand Down Expand Up @@ -32,7 +33,7 @@ + (UITabBarItem *)updateTabBarItem:(UITabBarItem *)tabItem bottomTabOptions:(RNN



[self appendTitleAttributes:tabItem textColor:[bottomTabOptions.textColor getWithDefaultValue:nil] selectedTextColor:[bottomTabOptions.selectedTextColor getWithDefaultValue:nil] fontFamily:[bottomTabOptions.fontFamily getWithDefaultValue:nil] fontSize:[bottomTabOptions.fontSize getWithDefaultValue:nil]];
[self appendTitleAttributes:tabItem textColor:[bottomTabOptions.textColor getWithDefaultValue:nil] selectedTextColor:[bottomTabOptions.selectedTextColor getWithDefaultValue:nil] fontFamily:[bottomTabOptions.fontFamily getWithDefaultValue:nil] fontSize:[bottomTabOptions.fontSize getWithDefaultValue:nil] fontWeight:[bottomTabOptions.fontWeight getWithDefaultValue:nil]];

return tabItem;
}
Expand Down Expand Up @@ -61,43 +62,13 @@ + (UIImage *)getIconImage:(UIImage *)icon withTint:(UIColor *)tintColor {
return nil;
}

+ (void)appendTitleAttributes:(UITabBarItem *)tabItem textColor:(UIColor *)textColor selectedTextColor:(UIColor *)selectedTextColor fontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize {
NSMutableDictionary* selectedAttributes = [NSMutableDictionary dictionaryWithDictionary:[tabItem titleTextAttributesForState:UIControlStateNormal]];
if (selectedTextColor) {
selectedAttributes[NSForegroundColorAttributeName] = selectedTextColor;
} else {
selectedAttributes[NSForegroundColorAttributeName] = [UIColor blackColor];
}

selectedAttributes[NSFontAttributeName] = [self tabBarTextFont:fontFamily fontSize:fontSize];
+ (void)appendTitleAttributes:(UITabBarItem *)tabItem textColor:(UIColor *)textColor selectedTextColor:(UIColor *)selectedTextColor fontFamily:(NSString *)fontFamily fontSize:(NSNumber *)fontSize fontWeight:(NSString *)fontWeight {
NSDictionary* selectedAttributes = [RNNFontAttributesCreator createWithDictionary:[tabItem titleTextAttributesForState:UIControlStateSelected] fontFamily:fontFamily fontSize:fontSize defaultFontSize:@(10) fontWeight:fontWeight color:selectedTextColor defaultColor:[UIColor blackColor]];
[tabItem setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected];


NSMutableDictionary* normalAttributes = [NSMutableDictionary dictionaryWithDictionary:[tabItem titleTextAttributesForState:UIControlStateNormal]];
if (textColor) {
normalAttributes[NSForegroundColorAttributeName] = textColor;
} else {
normalAttributes[NSForegroundColorAttributeName] = [UIColor blackColor];
}

normalAttributes[NSFontAttributeName] = [self tabBarTextFont:fontFamily fontSize:fontSize];
NSDictionary* normalAttributes = [RNNFontAttributesCreator createWithDictionary:[tabItem titleTextAttributesForState:UIControlStateNormal] fontFamily:fontFamily fontSize:fontSize defaultFontSize:@(10) fontWeight:fontWeight color:textColor defaultColor:[UIColor blackColor]];
[tabItem setTitleTextAttributes:normalAttributes forState:UIControlStateNormal];
}

+(UIFont *)tabBarTextFont:(NSString *)fontFamily fontSize:(NSNumber *)fontSize {
if (fontFamily) {
return [UIFont fontWithName:fontFamily size:[self fontSize:fontSize]];
}
else if (fontSize) {
return [UIFont systemFontOfSize:[self fontSize:fontSize]];
}
else {
return nil;
}
}

+ (CGFloat)fontSize:(NSNumber *)fontSize {
return fontSize ? [fontSize floatValue] : 10;
}

@end
1 change: 1 addition & 0 deletions lib/ios/RNNTitleOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@property (nonatomic, strong) Number* fontSize;
@property (nonatomic, strong) Color* color;
@property (nonatomic, strong) Text* fontFamily;
@property (nonatomic, strong) Text* fontWeight;

@property (nonatomic, strong) RNNComponentOptions* component;
@property (nonatomic, strong) Text* componentAlignment;
Expand Down
1 change: 1 addition & 0 deletions lib/ios/RNNTitleOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
self.text = [TextParser parse:dict key:@"text"];
self.fontFamily = [TextParser parse:dict key:@"fontFamily"];
self.fontSize = [NumberParser parse:dict key:@"fontSize"];
self.fontWeight = [TextParser parse:dict key:@"fontWeight"];
self.color = [ColorParser parse:dict key:@"color"];

self.component = [[RNNComponentOptions alloc] initWithDict:dict[@"component"]];
Expand Down
4 changes: 2 additions & 2 deletions lib/ios/RNNTitleViewHelper.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ -(UILabel*)setupSubtitle {
subtitleLabel.backgroundColor = [UIColor clearColor];
subtitleLabel.autoresizingMask = self.titleView.autoresizingMask;

NSDictionary* fontAttributes = [RNNFontAttributesCreator createFontAttributesWithFontFamily:[_subtitleOptions.fontFamily getWithDefaultValue:nil] fontSize:[_subtitleOptions.fontSize getWithDefaultValue:nil] color:[_subtitleOptions.color getWithDefaultValue:nil]];
NSDictionary* fontAttributes = [RNNFontAttributesCreator createWithFontFamily:[_subtitleOptions.fontFamily getWithDefaultValue:nil] fontSize:[_subtitleOptions.fontSize getWithDefaultValue:nil] fontWeight:[_subtitleOptions.fontWeight getWithDefaultValue:nil] color:[_subtitleOptions.color getWithDefaultValue:nil]];
[subtitleLabel setAttributedText:[[NSAttributedString alloc] initWithString:self.subtitle attributes:fontAttributes]];


Expand Down Expand Up @@ -128,7 +128,7 @@ -(UILabel*)setupTitle {

titleLabel.autoresizingMask = self.titleView.autoresizingMask;

NSDictionary* fontAttributes = [RNNFontAttributesCreator createFontAttributesWithFontFamily:[_titleOptions.fontFamily getWithDefaultValue:nil] fontSize:[_titleOptions.fontSize getWithDefaultValue:nil] color:[_subtitleOptions.color getWithDefaultValue:nil]];
NSDictionary* fontAttributes = [RNNFontAttributesCreator createWithFontFamily:[_titleOptions.fontFamily getWithDefaultValue:nil] fontSize:[_titleOptions.fontSize getWithDefaultValue:nil] fontWeight:[_titleOptions.fontWeight getWithDefaultValue:nil] color:[_subtitleOptions.color getWithDefaultValue:nil]];
[titleLabel setAttributedText:[[NSAttributedString alloc] initWithString:self.title attributes:fontAttributes]];

CGSize labelSize = [titleLabel.text sizeWithAttributes:fontAttributes];
Expand Down
Loading

0 comments on commit f283e15

Please sign in to comment.