diff --git a/Examples/2048/Game2048.js b/Examples/2048/Game2048.js
index 9ffaf42ba..009ba34a7 100644
--- a/Examples/2048/Game2048.js
+++ b/Examples/2048/Game2048.js
@@ -233,7 +233,7 @@ var styles = StyleSheet.create({
tryAgainText: {
color: '#ffffff',
fontSize: 20,
- fontWeight: 'bold',
+ fontWeight: '500',
},
cell: {
width: CELL_SIZE,
@@ -259,7 +259,7 @@ var styles = StyleSheet.create({
fontSize: 24,
color: '#776666',
fontFamily: 'Verdana',
- fontWeight: 'bold',
+ fontWeight: '500',
},
tile2: {
backgroundColor: '#eeeeee',
diff --git a/Examples/Movies/MovieCell.js b/Examples/Movies/MovieCell.js
index 21c90ec24..42781ec24 100644
--- a/Examples/Movies/MovieCell.js
+++ b/Examples/Movies/MovieCell.js
@@ -62,7 +62,7 @@ var styles = StyleSheet.create({
movieTitle: {
flex: 1,
fontSize: 16,
- fontWeight: 'bold',
+ fontWeight: '500',
marginBottom: 2,
},
movieYear: {
diff --git a/Examples/Movies/MovieScreen.js b/Examples/Movies/MovieScreen.js
index 980d51065..7c3ed316b 100644
--- a/Examples/Movies/MovieScreen.js
+++ b/Examples/Movies/MovieScreen.js
@@ -109,7 +109,7 @@ var styles = StyleSheet.create({
movieTitle: {
flex: 1,
fontSize: 16,
- fontWeight: 'bold',
+ fontWeight: '500',
},
rating: {
marginTop: 10,
@@ -119,7 +119,7 @@ var styles = StyleSheet.create({
},
ratingValue: {
fontSize: 28,
- fontWeight: 'bold',
+ fontWeight: '500',
},
mpaaWrapper: {
alignSelf: 'flex-start',
@@ -131,7 +131,7 @@ var styles = StyleSheet.create({
mpaaText: {
fontFamily: 'Palatino',
fontSize: 13,
- fontWeight: 'bold',
+ fontWeight: '500',
},
mainSection: {
flexDirection: 'row',
@@ -148,7 +148,7 @@ var styles = StyleSheet.create({
marginVertical: 10,
},
castTitle: {
- fontWeight: 'bold',
+ fontWeight: '500',
marginBottom: 3,
},
castActor: {
diff --git a/Examples/UIExplorer/ActionSheetIOSExample.js b/Examples/UIExplorer/ActionSheetIOSExample.js
index b6425c507..00e6830af 100644
--- a/Examples/UIExplorer/ActionSheetIOSExample.js
+++ b/Examples/UIExplorer/ActionSheetIOSExample.js
@@ -101,7 +101,7 @@ var ShareActionSheetExample = React.createClass({
var style = StyleSheet.create({
button: {
marginBottom: 10,
- fontWeight: 'bold',
+ fontWeight: '500',
}
});
diff --git a/Examples/UIExplorer/AdSupportIOSExample.js b/Examples/UIExplorer/AdSupportIOSExample.js
index 3c5ada96c..952cb7c8f 100644
--- a/Examples/UIExplorer/AdSupportIOSExample.js
+++ b/Examples/UIExplorer/AdSupportIOSExample.js
@@ -94,6 +94,6 @@ var AdSupportIOSExample = React.createClass({
var styles = StyleSheet.create({
title: {
- fontWeight: 'bold',
+ fontWeight: '500',
},
});
diff --git a/Examples/UIExplorer/DatePickerExample.js b/Examples/UIExplorer/DatePickerExample.js
index 35fa869f3..cf4fa83d9 100644
--- a/Examples/UIExplorer/DatePickerExample.js
+++ b/Examples/UIExplorer/DatePickerExample.js
@@ -149,14 +149,14 @@ var styles = StyleSheet.create({
paddingVertical: 2,
},
label: {
- fontWeight: 'bold',
+ fontWeight: '500',
},
headingContainer: {
padding: 4,
backgroundColor: '#f6f7f8',
},
heading: {
- fontWeight: 'bold',
+ fontWeight: '500',
fontSize: 14,
},
});
diff --git a/Examples/UIExplorer/GeolocationExample.js b/Examples/UIExplorer/GeolocationExample.js
index 82f1c83eb..5d49f341e 100644
--- a/Examples/UIExplorer/GeolocationExample.js
+++ b/Examples/UIExplorer/GeolocationExample.js
@@ -74,6 +74,6 @@ var GeolocationExample = React.createClass({
var styles = StyleSheet.create({
title: {
- fontWeight: 'bold',
+ fontWeight: '500',
},
});
diff --git a/Examples/UIExplorer/NavigatorIOSExample.js b/Examples/UIExplorer/NavigatorIOSExample.js
index 56bb6ab78..fd05caf14 100644
--- a/Examples/UIExplorer/NavigatorIOSExample.js
+++ b/Examples/UIExplorer/NavigatorIOSExample.js
@@ -214,7 +214,7 @@ var styles = StyleSheet.create({
},
rowText: {
fontSize: 17,
- fontWeight: 'bold',
+ fontWeight: '500',
},
});
diff --git a/Examples/UIExplorer/ReactNavigator/BreadcrumbNavSample.js b/Examples/UIExplorer/ReactNavigator/BreadcrumbNavSample.js
index 451da6656..17be12f8d 100644
--- a/Examples/UIExplorer/ReactNavigator/BreadcrumbNavSample.js
+++ b/Examples/UIExplorer/ReactNavigator/BreadcrumbNavSample.js
@@ -254,7 +254,7 @@ var styles = StyleSheet.create({
fontSize: 18,
color: '#666666',
textAlign: 'center',
- fontWeight: 'bold',
+ fontWeight: '500',
lineHeight: 32,
},
filterText: {
diff --git a/Examples/UIExplorer/ReactNavigator/NavigationBarSample.js b/Examples/UIExplorer/ReactNavigator/NavigationBarSample.js
index ddb225552..5096cab71 100644
--- a/Examples/UIExplorer/ReactNavigator/NavigationBarSample.js
+++ b/Examples/UIExplorer/ReactNavigator/NavigationBarSample.js
@@ -107,7 +107,7 @@ var styles = StyleSheet.create({
},
navBarTitleText: {
color: cssVar('fbui-bluegray-60'),
- fontWeight: 'bold',
+ fontWeight: '500',
marginVertical: 9,
},
navBarButtonText: {
diff --git a/Examples/UIExplorer/ReactNavigator/NestedBreadcrumbNavSample.js b/Examples/UIExplorer/ReactNavigator/NestedBreadcrumbNavSample.js
index 263d8b738..20d857472 100644
--- a/Examples/UIExplorer/ReactNavigator/NestedBreadcrumbNavSample.js
+++ b/Examples/UIExplorer/ReactNavigator/NestedBreadcrumbNavSample.js
@@ -176,7 +176,7 @@ var styles = StyleSheet.create({
fontSize: 18,
color: '#666666',
textAlign: 'center',
- fontWeight: 'bold',
+ fontWeight: '500',
lineHeight: 32,
},
filterText: {
diff --git a/Examples/UIExplorer/SliderIOSExample.js b/Examples/UIExplorer/SliderIOSExample.js
index ae6aca144..13eee593a 100644
--- a/Examples/UIExplorer/SliderIOSExample.js
+++ b/Examples/UIExplorer/SliderIOSExample.js
@@ -47,7 +47,7 @@ var styles = StyleSheet.create({
text: {
fontSize: 14,
textAlign: 'center',
- fontWeight: 'bold',
+ fontWeight: '500',
margin: 10,
},
});
diff --git a/Examples/UIExplorer/TextExample.ios.js b/Examples/UIExplorer/TextExample.ios.js
index e29b07da4..e88bc4a0c 100644
--- a/Examples/UIExplorer/TextExample.ios.js
+++ b/Examples/UIExplorer/TextExample.ios.js
@@ -29,7 +29,7 @@ var Entity = React.createClass({
var AttributeToggler = React.createClass({
getInitialState: function() {
- return {fontWeight: 'bold', fontSize: 15};
+ return {fontWeight: '500', fontSize: 15};
},
increaseSize: function() {
this.setState({
@@ -129,9 +129,37 @@ exports.examples = [
title: 'Font Weight',
render: function() {
return (
-
- Move fast and be bold
-
+
+
+ Move fast and be ultralight
+
+
+ Move fast and be light
+
+
+ Move fast and be normal
+
+
+ Move fast and be bold
+
+
+ Move fast and be ultrabold
+
+
+ );
+ },
+}, {
+ title: 'Font Style',
+ render: function() {
+ return (
+
+
+ Normal text
+
+
+ Italic text
+
+
);
},
}, {
@@ -279,7 +307,7 @@ var styles = StyleSheet.create({
backgroundColor: 'rgba(100, 100, 100, 0.3)'
},
entity: {
- fontWeight: 'bold',
+ fontWeight: '500',
color: '#527fe4',
},
});
diff --git a/Examples/UIExplorer/TouchableExample.js b/Examples/UIExplorer/TouchableExample.js
index 35d86aaf8..6b3c611ed 100644
--- a/Examples/UIExplorer/TouchableExample.js
+++ b/Examples/UIExplorer/TouchableExample.js
@@ -187,7 +187,7 @@ var styles = StyleSheet.create({
backgroundColor: '#f9f9f9',
},
textBlock: {
- fontWeight: 'bold',
+ fontWeight: '500',
color: 'blue',
},
});
diff --git a/Examples/UIExplorer/UIExplorerBlock.js b/Examples/UIExplorer/UIExplorerBlock.js
index 66222fd05..7d2de002f 100644
--- a/Examples/UIExplorer/UIExplorerBlock.js
+++ b/Examples/UIExplorer/UIExplorerBlock.js
@@ -76,7 +76,7 @@ var styles = StyleSheet.create({
},
titleText: {
fontSize: 14,
- fontWeight: 'bold',
+ fontWeight: '500',
},
descriptionText: {
fontSize: 14,
diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js
index 73f016cdd..a13da34dc 100644
--- a/Examples/UIExplorer/UIExplorerList.js
+++ b/Examples/UIExplorer/UIExplorerList.js
@@ -204,7 +204,7 @@ var styles = StyleSheet.create({
backgroundColor: 'white',
},
sectionHeaderTitle: {
- fontWeight: 'bold',
+ fontWeight: '500',
fontSize: 11,
},
row: {
@@ -220,7 +220,7 @@ var styles = StyleSheet.create({
},
rowTitleText: {
fontSize: 17,
- fontWeight: 'bold',
+ fontWeight: '500',
},
rowDetailText: {
fontSize: 15,
diff --git a/Examples/UIExplorer/UIExplorerTitle.js b/Examples/UIExplorer/UIExplorerTitle.js
index 2016ee085..7a8895413 100644
--- a/Examples/UIExplorer/UIExplorerTitle.js
+++ b/Examples/UIExplorer/UIExplorerTitle.js
@@ -42,7 +42,7 @@ var styles = StyleSheet.create({
},
text: {
fontSize: 19,
- fontWeight: 'bold',
+ fontWeight: '500',
},
});
diff --git a/Examples/UIExplorer/WebViewExample.js b/Examples/UIExplorer/WebViewExample.js
index 3dcf7c8b7..a471a7807 100644
--- a/Examples/UIExplorer/WebViewExample.js
+++ b/Examples/UIExplorer/WebViewExample.js
@@ -239,7 +239,7 @@ var styles = StyleSheet.create({
},
errorTextTitle: {
fontSize: 15,
- fontWeight: 'bold',
+ fontWeight: '500',
marginBottom: 10,
},
errorText: {
diff --git a/IntegrationTests/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js
index de1703528..dbb5dde83 100644
--- a/IntegrationTests/IntegrationTestsApp.js
+++ b/IntegrationTests/IntegrationTestsApp.js
@@ -81,7 +81,7 @@ var styles = StyleSheet.create({
padding: 10,
},
testName: {
- fontWeight: 'bold',
+ fontWeight: '500',
},
separator: {
height: 1,
diff --git a/Libraries/Text/RCTShadowText.h b/Libraries/Text/RCTShadowText.h
index 61c8f2e73..b14a623c8 100644
--- a/Libraries/Text/RCTShadowText.h
+++ b/Libraries/Text/RCTShadowText.h
@@ -21,6 +21,7 @@ extern NSString *const RCTReactTagAttributeName;
@property (nonatomic, copy) NSString *fontFamily;
@property (nonatomic, assign) CGFloat fontSize;
@property (nonatomic, copy) NSString *fontWeight;
+@property (nonatomic, copy) NSString *fontStyle;
@property (nonatomic, assign) BOOL isHighlighted;
@property (nonatomic, assign) CGFloat lineHeight;
@property (nonatomic, assign) NSInteger maxNumberOfLines;
diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m
index 8899fea87..f00350205 100644
--- a/Libraries/Text/RCTShadowText.m
+++ b/Libraries/Text/RCTShadowText.m
@@ -50,12 +50,14 @@ static css_dim_t RCTMeasure(void *context, float width)
{
return [self _attributedStringWithFontFamily:nil
fontSize:0
- fontWeight:nil];
+ fontWeight:nil
+ fontStyle:nil];
}
- (NSAttributedString *)_attributedStringWithFontFamily:(NSString *)fontFamily
fontSize:(CGFloat)fontSize
fontWeight:(NSString *)fontWeight
+ fontStyle:(NSString *)fontStyle
{
if (![self isTextDirty] && _cachedAttributedString) {
return _cachedAttributedString;
@@ -67,6 +69,9 @@ static css_dim_t RCTMeasure(void *context, float width)
if (_fontWeight) {
fontWeight = _fontWeight;
}
+ if (_fontStyle) {
+ fontStyle = _fontStyle;
+ }
if (_fontFamily) {
fontFamily = _fontFamily;
}
@@ -75,7 +80,7 @@ static css_dim_t RCTMeasure(void *context, float width)
for (RCTShadowView *child in [self reactSubviews]) {
if ([child isKindOfClass:[RCTShadowText class]]) {
RCTShadowText *shadowText = (RCTShadowText *)child;
- [attributedString appendAttributedString:[shadowText _attributedStringWithFontFamily:fontFamily fontSize:fontSize fontWeight:fontWeight]];
+ [attributedString appendAttributedString:[shadowText _attributedStringWithFontFamily:fontFamily fontSize:fontSize fontWeight:fontWeight fontStyle:fontStyle]];
} else if ([child isKindOfClass:[RCTShadowRawText class]]) {
RCTShadowRawText *shadowRawText = (RCTShadowRawText *)child;
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:[shadowRawText text] ?: @""]];
@@ -96,7 +101,7 @@ static css_dim_t RCTMeasure(void *context, float width)
[self _addAttribute:NSBackgroundColorAttributeName withValue:self.textBackgroundColor toAttributedString:attributedString];
}
- _font = [RCTConvert UIFont:nil withFamily:fontFamily size:@(fontSize) weight:fontWeight];
+ _font = [RCTConvert UIFont:nil withFamily:fontFamily size:@(fontSize) weight:fontWeight style:fontStyle];
[self _addAttribute:NSFontAttributeName withValue:_font toAttributedString:attributedString];
[self _addAttribute:RCTReactTagAttributeName withValue:self.reactTag toAttributedString:attributedString];
[self _setParagraphStyleOnAttributedString:attributedString];
@@ -110,7 +115,7 @@ static css_dim_t RCTMeasure(void *context, float width)
- (UIFont *)font
{
- return _font ?: [RCTConvert UIFont:nil withFamily:_fontFamily size:@(_fontSize) weight:_fontWeight];
+ return _font ?: [RCTConvert UIFont:nil withFamily:_fontFamily size:@(_fontSize) weight:_fontWeight style:_fontStyle];
}
- (void)_addAttribute:(NSString *)attribute withValue:(id)attributeValue toAttributedString:(NSMutableAttributedString *)attributedString
diff --git a/ReactKit/Base/RCTConvert.h b/ReactKit/Base/RCTConvert.h
index f26dea827..fb4f51883 100644
--- a/ReactKit/Base/RCTConvert.h
+++ b/ReactKit/Base/RCTConvert.h
@@ -12,6 +12,7 @@
#import "Layout.h"
#import "RCTAnimationType.h"
+#import "RCTLog.h"
#import "RCTPointerEvents.h"
/**
@@ -69,8 +70,13 @@
+ (UIFont *)UIFont:(UIFont *)font withSize:(id)json;
+ (UIFont *)UIFont:(UIFont *)font withWeight:(id)json;
++ (UIFont *)UIFont:(UIFont *)font withStyle:(id)json;
+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)json;
-+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)json size:(id)json weight:(id)json;
++ (UIFont *)UIFont:(UIFont *)font
+ withFamily:(id)family
+ size:(id)size
+ weight:(id)weight
+ style:(id)style;
+ (NSArray *)NSStringArray:(id)json;
+ (NSArray *)NSURLArray:(id)json;
diff --git a/ReactKit/Base/RCTConvert.m b/ReactKit/Base/RCTConvert.m
index dd46fb4af..01300e306 100644
--- a/ReactKit/Base/RCTConvert.m
+++ b/ReactKit/Base/RCTConvert.m
@@ -11,8 +11,6 @@
#import
-#import "RCTLog.h"
-
@implementation RCTConvert
RCT_CONVERTER(BOOL, BOOL, boolValue)
@@ -135,7 +133,9 @@ RCT_CGSTRUCT_CONVERTER(CATransform3D, (@[
@"m41", @"m42", @"m43", @"m44"
]), nil)
-RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty"]), nil)
+RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[
+ @"a", @"b", @"c", @"d", @"tx", @"ty"
+]), nil)
+ (UIColor *)UIColor:(id)json
{
@@ -364,7 +364,8 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty
} else if (json && ![json isKindOfClass:[NSNull class]]) {
- RCTLogError(@"Expected NSArray, NSDictionary or NSString for UIColor, received %@: %@", [json class], json);
+ RCTLogError(@"Expected NSArray, NSDictionary or NSString for UIColor, \
+ received %@: %@", [json class], json);
}
// Default color
@@ -418,100 +419,163 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty
return [self UIImage:json].CGImage;
}
+#ifndef __IPHONE_8_2
+
+// These constants are defined in iPhone SDK 8.2
+// They'll work fine in earlier iOS versions, but the app cannot be built with
+// an SDK version < 8.2 unless we redefine them here. This will be removed
+// in a future version of ReactKit, once 8.2 is more widely adopted.
+
+static const CGFloat UIFontWeightUltraLight = -0.8;
+static const CGFloat UIFontWeightThin = -0.6;
+static const CGFloat UIFontWeightLight = -0.4;
+static const CGFloat UIFontWeightRegular = 0;
+static const CGFloat UIFontWeightMedium = 0.23;
+static const CGFloat UIFontWeightSemibold = 0.3;
+static const CGFloat UIFontWeightBold = 0.4;
+static const CGFloat UIFontWeightHeavy = 0.56;
+static const CGFloat UIFontWeightBlack = 0.62;
+
+#endif
+
+typedef CGFloat RCTFontWeight;
+RCT_ENUM_CONVERTER(RCTFontWeight, (@{
+ @"normal": @(UIFontWeightRegular),
+ @"bold": @(UIFontWeightBold),
+ @"100": @(UIFontWeightUltraLight),
+ @"200": @(UIFontWeightThin),
+ @"300": @(UIFontWeightLight),
+ @"400": @(UIFontWeightRegular),
+ @"500": @(UIFontWeightMedium),
+ @"600": @(UIFontWeightSemibold),
+ @"700": @(UIFontWeightBold),
+ @"800": @(UIFontWeightHeavy),
+ @"900": @(UIFontWeightBlack),
+}), UIFontWeightRegular, doubleValue)
+
+typedef BOOL RCTFontStyle;
+RCT_ENUM_CONVERTER(RCTFontStyle, (@{
+ @"normal": @NO,
+ @"italic": @YES,
+ @"oblique": @YES,
+}), NO, boolValue)
+
+static RCTFontWeight RCTWeightOfFont(UIFont *font)
+{
+ NSDictionary *traits = [font.fontDescriptor objectForKey:UIFontDescriptorTraitsAttribute];
+ return [traits[UIFontWeightTrait] doubleValue];
+}
+
+static BOOL RCTFontIsItalic(UIFont *font)
+{
+ NSDictionary *traits = [font.fontDescriptor objectForKey:UIFontDescriptorTraitsAttribute];
+ UIFontDescriptorSymbolicTraits symbolicTraits = [traits[UIFontSymbolicTrait] unsignedIntValue];
+ return (symbolicTraits & UIFontDescriptorTraitItalic) != 0;
+}
+
+static BOOL RCTFontIsCondensed(UIFont *font)
+{
+ NSDictionary *traits = [font.fontDescriptor objectForKey:UIFontDescriptorTraitsAttribute];
+ UIFontDescriptorSymbolicTraits symbolicTraits = [traits[UIFontSymbolicTrait] unsignedIntValue];
+ return (symbolicTraits & UIFontDescriptorTraitCondensed) != 0;
+}
+
+ (UIFont *)UIFont:(UIFont *)font withSize:(id)json
{
- return [self UIFont:font withFamily:nil size:json weight:nil];
+ return [self UIFont:font withFamily:nil size:json weight:nil style:nil];
}
+ (UIFont *)UIFont:(UIFont *)font withWeight:(id)json
{
- return [self UIFont:font withFamily:nil size:nil weight:json];
+ return [self UIFont:font withFamily:nil size:nil weight:json style:nil];
+}
+
++ (UIFont *)UIFont:(UIFont *)font withStyle:(id)json
+{
+ return [self UIFont:font withFamily:nil size:nil weight:nil style:json];
}
+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)json
{
- return [self UIFont:font withFamily:json size:nil weight:nil];
+ return [self UIFont:font withFamily:json size:nil weight:nil style:nil];
}
-+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)family size:(id)size weight:(id)weight
++ (UIFont *)UIFont:(UIFont *)font
+ withFamily:(id)family
+ size:(id)size
+ weight:(id)weight
+ style:(id)style
{
- CGFloat const RCTDefaultFontSize = 14;
- NSString *const RCTDefaultFontName = @"HelveticaNeue";
- NSString *const RCTDefaultFontWeight = @"normal";
- NSString *const RCTBoldFontWeight = @"bold";
+ // Defaults
+ NSString *const RCTDefaultFontFamily = @"Helvetica Neue";
+ const RCTFontWeight RCTDefaultFontWeight = UIFontWeightRegular;
+ const CGFloat RCTDefaultFontSize = 14;
- // Create descriptor
- UIFontDescriptor *fontDescriptor = font.fontDescriptor ?: [UIFontDescriptor fontDescriptorWithName:RCTDefaultFontName size:RCTDefaultFontSize];
-
- // Get font size
- CGFloat fontSize = [self CGFloat:size];
- if (fontSize && !isnan(fontSize)) {
- fontDescriptor = [fontDescriptor fontDescriptorWithSize:fontSize];
- }
-
- // Get font family
- NSString *familyName = [self NSString:family];
- if (familyName) {
- if ([UIFont fontNamesForFamilyName:familyName].count == 0) {
- font = [UIFont fontWithName:familyName size:fontDescriptor.pointSize];
- if (font) {
- // It's actually a font name, not a font family name,
- // but we'll do what was meant, not what was said.
- familyName = font.familyName;
- fontDescriptor = font.fontDescriptor;
- } else {
- // Not a valid font or family
- RCTLogError(@"Unrecognized font family '%@'", familyName);
- familyName = [UIFont fontWithDescriptor:fontDescriptor size:0].familyName;
- }
- } else {
- // Set font family
- fontDescriptor = [fontDescriptor fontDescriptorWithFamily:familyName];
- }
- } else {
- familyName = [UIFont fontWithDescriptor:fontDescriptor size:0].familyName;
+ // Get existing properties
+ BOOL isItalic = NO;
+ BOOL isCondensed = NO;
+ RCTFontWeight fontWeight = RCTDefaultFontWeight;
+ if (font) {
+ family = font.familyName;
+ fontWeight = RCTWeightOfFont(font);
+ isItalic = RCTFontIsItalic(font);
+ isCondensed = RCTFontIsCondensed(font);
}
// Get font weight
- NSString *fontWeight = [self NSString:weight];
- if (fontWeight) {
+ if (weight) {
+ fontWeight = [self RCTFontWeight:weight];
+ }
- static NSSet *values;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- values = [NSSet setWithObjects:RCTDefaultFontWeight, RCTBoldFontWeight, nil];
- });
+ // Get font style
+ if (style) {
+ isItalic = [self RCTFontStyle:style];
+ }
- if (fontWeight && ![values containsObject:fontWeight]) {
- RCTLogError(@"Unrecognized font weight '%@', must be one of %@", fontWeight, values);
- fontWeight = RCTDefaultFontWeight;
+ // Get font size
+ CGFloat fontSize = [self CGFloat:size] ?: RCTDefaultFontSize;
+
+ // Get font family
+ NSString *familyName = [self NSString:family] ?: RCTDefaultFontFamily;
+ if ([UIFont fontNamesForFamilyName:familyName].count == 0) {
+ font = [UIFont fontWithName:familyName size:fontSize];
+ if (font) {
+ // It's actually a font name, not a font family name,
+ // but we'll do what was meant, not what was said.
+ familyName = font.familyName;
+ NSDictionary *traits = [font.fontDescriptor objectForKey:UIFontDescriptorTraitsAttribute];
+ fontWeight = [traits[UIFontWeightTrait] doubleValue];
+ } else {
+ // Not a valid font or family
+ RCTLogError(@"Unrecognized font family '%@'", familyName);
+ familyName = RCTDefaultFontFamily;
}
+ }
- // this is hacky. we are appending the string -Medium because most fonts we currently use
- // just need to have -Medium appended to get the bold we want. we're going to revamp this
- // to make it easier to know which options are available in JS. t4996115
- if ([fontWeight isEqualToString:RCTBoldFontWeight]) {
- font = nil;
- for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
- if ([fontName hasSuffix:@"-Medium"]) {
- font = [UIFont fontWithName:fontName size:fontDescriptor.pointSize];
- break;
- }
- if ([fontName hasSuffix:@"-Bold"]) {
- font = [UIFont fontWithName:fontName size:fontDescriptor.pointSize];
- // But keep searching in case there's a medium option
- }
- }
- if (font) {
- fontDescriptor = font.fontDescriptor;
+ // Get closest match
+ UIFont *bestMatch = font;
+ CGFloat closestWeight = font ? RCTWeightOfFont(font) : INFINITY;
+ for (NSString *name in [UIFont fontNamesForFamilyName:familyName]) {
+ UIFont *match = [UIFont fontWithName:name size:fontSize];
+ if (isItalic == RCTFontIsItalic(match) &&
+ isCondensed == RCTFontIsCondensed(match)) {
+ CGFloat testWeight = RCTWeightOfFont(match);
+ if (ABS(testWeight - fontWeight) < ABS(closestWeight - fontWeight)) {
+ bestMatch = match;
+ closestWeight = testWeight;
}
}
}
- // TODO: font style
+ // Safety net
+ if (!bestMatch) {
+ RCTLogError(@"Could not find font with family: '%@', size: %@, \
+ weight: %@, style: %@", family, size, weight, style);
+ bestMatch = [UIFont fontWithName:[[UIFont fontNamesForFamilyName:familyName] firstObject]
+ size:fontSize];
+ }
- // Create font
- return [UIFont fontWithDescriptor:fontDescriptor size:0];
+ return bestMatch;
}
RCT_ARRAY_CONVERTER(NSString)
diff --git a/ReactKit/Base/RCTUtils.m b/ReactKit/Base/RCTUtils.m
index 70ad4479a..300f6d721 100644
--- a/ReactKit/Base/RCTUtils.m
+++ b/ReactKit/Base/RCTUtils.m
@@ -50,11 +50,11 @@ NSString *RCTMD5Hash(NSString *string)
CC_MD5(str, (CC_LONG)strlen(str), result);
return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- result[0], result[1], result[2], result[3],
- result[4], result[5], result[6], result[7],
- result[8], result[9], result[10], result[11],
- result[12], result[13], result[14], result[15]
- ];
+ result[0], result[1], result[2], result[3],
+ result[4], result[5], result[6], result[7],
+ result[8], result[9], result[10], result[11],
+ result[12], result[13], result[14], result[15]
+ ];
}
CGFloat RCTScreenScale()
diff --git a/ReactKit/Views/RCTTextFieldManager.m b/ReactKit/Views/RCTTextFieldManager.m
index 041886e55..8418c8858 100644
--- a/ReactKit/Views/RCTTextFieldManager.m
+++ b/ReactKit/Views/RCTTextFieldManager.m
@@ -41,7 +41,11 @@ RCT_CUSTOM_VIEW_PROPERTY(fontSize, RCTTextField)
}
RCT_CUSTOM_VIEW_PROPERTY(fontWeight, RCTTextField)
{
- view.font = [RCTConvert UIFont:view.font withWeight:json]; // TODO: default value
+ view.font = [RCTConvert UIFont:view.font withWeight:json]; // defaults to normal
+}
+RCT_CUSTOM_VIEW_PROPERTY(fontStyle, RCTTextField)
+{
+ view.font = [RCTConvert UIFont:view.font withStyle:json]; // defaults to normal
}
RCT_CUSTOM_VIEW_PROPERTY(fontFamily, RCTTextField)
{