Skip to content

Commit

Permalink
Fix styling of system fonts
Browse files Browse the repository at this point in the history
Summary:
When you call `-[RCTConvert UIFont:withFamily:...]` with a non-nil font object, we'll try to use the existing font object for system information. On iOS9+ which uses the San Francisco font, `[UIFont fontNamesForFamilyName:]` doesn't return anything useful, so we need to make sure that we detect this as a system font and use the appropriate methods. This issues is made worse by the fact that RCTTextView and friends recreate the font property for every attribute that is set (pretty horrible perf-wise).

This fixes #2140

Reviewed By: sahrens

Differential Revision: D3662751

fbshipit-source-id: c528e8945ed361a922c03f861d3c0b584658573b
  • Loading branch information
javache authored and Facebook Github Bot 2 committed Aug 5, 2016
1 parent 8f75d73 commit e30327c
Showing 1 changed file with 18 additions and 37 deletions.
55 changes: 18 additions & 37 deletions React/Base/RCTConvert.m
Original file line number Diff line number Diff line change
Expand Up @@ -481,24 +481,6 @@ + (CGColorRef)CGColor:(id)json
return [self UIColor:json].CGColor;
}

#if !defined(__IPHONE_8_2) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_2

// These constants are defined in iPhone SDK 8.2, but the app cannot run on
// iOS < 8.2 unless we redefine them here. If you target iOS 8.2 or above
// as a base target, the standard constants will be used instead.

#define UIFontWeightUltraLight -0.8
#define UIFontWeightThin -0.6
#define UIFontWeightLight -0.4
#define UIFontWeightRegular 0
#define UIFontWeightMedium 0.23
#define UIFontWeightSemibold 0.3
#define UIFontWeightBold 0.4
#define UIFontWeightHeavy 0.56
#define UIFontWeightBlack 0.62

#endif

typedef CGFloat RCTFontWeight;
RCT_ENUM_CONVERTER(RCTFontWeight, (@{
@"normal": @(UIFontWeightRegular),
Expand Down Expand Up @@ -575,49 +557,52 @@ + (UIFont *)UIFont:(id)json
size:json[@"fontSize"]
weight:json[@"fontWeight"]
style:json[@"fontStyle"]
scaleMultiplier:1.0f];
scaleMultiplier:1];
}

+ (UIFont *)UIFont:(UIFont *)font withSize:(id)json
{
return [self UIFont:font withFamily:nil size:json weight:nil style:nil scaleMultiplier:1.0];
return [self UIFont:font withFamily:nil size:json weight:nil style:nil scaleMultiplier:1];
}

+ (UIFont *)UIFont:(UIFont *)font withWeight:(id)json
{
return [self UIFont:font withFamily:nil size:nil weight:json style:nil scaleMultiplier:1.0];
return [self UIFont:font withFamily:nil size:nil weight:json style:nil scaleMultiplier:1];
}

+ (UIFont *)UIFont:(UIFont *)font withStyle:(id)json
{
return [self UIFont:font withFamily:nil size:nil weight:nil style:json scaleMultiplier:1.0];
return [self UIFont:font withFamily:nil size:nil weight:nil style:json scaleMultiplier:1];
}

+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)json
{
return [self UIFont:font withFamily:json size:nil weight:nil style:nil scaleMultiplier:1.0];
return [self UIFont:font withFamily:json size:nil weight:nil style:nil scaleMultiplier:1];
}

+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)family
size:(id)size weight:(id)weight style:(id)style
scaleMultiplier:(CGFloat)scaleMultiplier
{
// Defaults
NSString *const RCTDefaultFontFamily = @"System";
NSString *const RCTIOS8SystemFontFamily = @"Helvetica Neue";
const RCTFontWeight RCTDefaultFontWeight = UIFontWeightRegular;
const CGFloat RCTDefaultFontSize = 14;
static NSString *defaultFontFamily;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
defaultFontFamily = [UIFont systemFontOfSize:14].familyName;
});
const RCTFontWeight defaultFontWeight = UIFontWeightRegular;
const CGFloat defaultFontSize = 14;

// Initialize properties to defaults
CGFloat fontSize = RCTDefaultFontSize;
RCTFontWeight fontWeight = RCTDefaultFontWeight;
NSString *familyName = RCTDefaultFontFamily;
CGFloat fontSize = defaultFontSize;
RCTFontWeight fontWeight = defaultFontWeight;
NSString *familyName = defaultFontFamily;
BOOL isItalic = NO;
BOOL isCondensed = NO;

if (font) {
familyName = font.familyName ?: RCTDefaultFontFamily;
fontSize = font.pointSize ?: RCTDefaultFontSize;
familyName = font.familyName ?: defaultFontFamily;
fontSize = font.pointSize ?: defaultFontSize;
fontWeight = RCTWeightOfFont(font);
isItalic = RCTFontIsItalic(font);
isCondensed = RCTFontIsCondensed(font);
Expand All @@ -634,7 +619,7 @@ + (UIFont *)UIFont:(UIFont *)font withFamily:(id)family

// Handle system font as special case. This ensures that we preserve
// the specific metrics of the standard system font as closely as possible.
if ([familyName isEqual:RCTDefaultFontFamily]) {
if ([familyName isEqual:defaultFontFamily] || [familyName isEqualToString:@"System"]) {
if ([UIFont respondsToSelector:@selector(systemFontOfSize:weight:)]) {
font = [UIFont systemFontOfSize:fontSize weight:fontWeight];
if (isItalic || isCondensed) {
Expand All @@ -650,10 +635,6 @@ + (UIFont *)UIFont:(UIFont *)font withFamily:(id)family
font = [UIFont fontWithDescriptor:fontDescriptor size:fontSize];
}
return font;
} else {
// systemFontOfSize:weight: isn't available prior to iOS 8.2, so we
// fall back to finding the correct font manually, by linear search.
familyName = RCTIOS8SystemFontFamily;
}
}

Expand Down

0 comments on commit e30327c

Please sign in to comment.