Allow iOS PlatformColor strings to be ObjC or Swift UIColor selectors (#28703)

Summary:
Per discussion in https://github.com/react-native-community/releases/issues/186 the iOS `PlatformColor()` function is documented to use the semantic color names provided by the system.   The referenced HIG documentation itself links to the `UIColor` documentation for semantic colors names.   However, these names differ depending on if you are viewing the new Swift API docs or the Objective C docs.   The current Objective C implementation in react-native assumes Objective C UIColor selector names that are suffixed 'Color'.   But in Swift, Apple provides a Swift Extension on UIColor that makes aliases without the the 'Color' suffix and then makes the original selectors invalid presumably via `NS_UNAVAILABLE_SWIFT`.

Since both selector names are valid depending on if you are using Objective C or Swift, let's make both forms be legal for `PlatformColor()`.   In `RCTConvert.m` there is a dictionary of legal selector names.   The code already supports the ability to have names be aliases of other selectors via a RCTSelector metadata key.   The change adds code to the initialization of the map: it iterates over the keys in the map, which are all ObjC style UIColor selectors, and creates aliases by duplicating the entries, creating key names by stripping off the ObjC "Color" suffix, adds the RCTSelector key referring to the original and then appends these new Swift aliases to the map.

## Changelog

[iOS] [Changed] - Allow iOS PlatformColor strings to be ObjC or Swift UIColor selectors
Pull Request resolved: https://github.com/facebook/react-native/pull/28703

Test Plan:
The PlatformColorExample.js is updated to use the new, shorter Swift selector names.   There are still other examples in the same file and in unit tests that exercise the ObjC selector names.

<img width="492" alt="PlatformColor" src="https://user-images.githubusercontent.com/30053638/79809089-89ab7d00-8324-11ea-8a9d-120b92edeedf.png">

Reviewed By: shergin

Differential Revision: D21147404

Pulled By: TheSavior

fbshipit-source-id: 0273ec855e426b3a7ba97a87645859e05bcd4126
This commit is contained in:
Tom Underhill 2020-04-20 20:20:02 -07:00 коммит произвёл Facebook GitHub Bot
Родитель d639063499
Коммит 25793eab56
2 изменённых файлов: 69 добавлений и 52 удалений

Просмотреть файл

@ -22,94 +22,94 @@ function PlatformColorsExample() {
colors = [
// https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors
// Label Colors
{label: 'labelColor', color: PlatformColor('labelColor')},
{label: 'label', color: PlatformColor('label')},
{
label: 'secondaryLabelColor',
color: PlatformColor('secondaryLabelColor'),
label: 'secondaryLabel',
color: PlatformColor('secondaryLabel'),
},
{
label: 'tertiaryLabelColor',
color: PlatformColor('tertiaryLabelColor'),
label: 'tertiaryLabel',
color: PlatformColor('tertiaryLabel'),
},
{
label: 'quaternaryLabelColor',
color: PlatformColor('quaternaryLabelColor'),
label: 'quaternaryLabel',
color: PlatformColor('quaternaryLabel'),
},
// Fill Colors
{label: 'systemFillColor', color: PlatformColor('systemFillColor')},
{label: 'systemFill', color: PlatformColor('systemFill')},
{
label: 'secondarySystemFillColor',
color: PlatformColor('secondarySystemFillColor'),
label: 'secondarySystemFill',
color: PlatformColor('secondarySystemFill'),
},
{
label: 'tertiarySystemFillColor',
color: PlatformColor('tertiarySystemFillColor'),
label: 'tertiarySystemFill',
color: PlatformColor('tertiarySystemFill'),
},
{
label: 'quaternarySystemFillColor',
color: PlatformColor('quaternarySystemFillColor'),
label: 'quaternarySystemFill',
color: PlatformColor('quaternarySystemFill'),
},
// Text Colors
{
label: 'placeholderTextColor',
color: PlatformColor('placeholderTextColor'),
label: 'placeholderText',
color: PlatformColor('placeholderText'),
},
// Standard Content Background Colors
{
label: 'systemBackgroundColor',
color: PlatformColor('systemBackgroundColor'),
label: 'systemBackground',
color: PlatformColor('systemBackground'),
},
{
label: 'secondarySystemBackgroundColor',
color: PlatformColor('secondarySystemBackgroundColor'),
label: 'secondarySystemBackground',
color: PlatformColor('secondarySystemBackground'),
},
{
label: 'tertiarySystemBackgroundColor',
color: PlatformColor('tertiarySystemBackgroundColor'),
label: 'tertiarySystemBackground',
color: PlatformColor('tertiarySystemBackground'),
},
// Grouped Content Background Colors
{
label: 'systemGroupedBackgroundColor',
color: PlatformColor('systemGroupedBackgroundColor'),
label: 'systemGroupedBackground',
color: PlatformColor('systemGroupedBackground'),
},
{
label: 'secondarySystemGroupedBackgroundColor',
color: PlatformColor('secondarySystemGroupedBackgroundColor'),
label: 'secondarySystemGroupedBackground',
color: PlatformColor('secondarySystemGroupedBackground'),
},
{
label: 'tertiarySystemGroupedBackgroundColor',
color: PlatformColor('tertiarySystemGroupedBackgroundColor'),
label: 'tertiarySystemGroupedBackground',
color: PlatformColor('tertiarySystemGroupedBackground'),
},
// Separator Colors
{label: 'separatorColor', color: PlatformColor('separatorColor')},
{label: 'separator', color: PlatformColor('separator')},
{
label: 'opaqueSeparatorColor',
color: PlatformColor('opaqueSeparatorColor'),
label: 'opaqueSeparator',
color: PlatformColor('opaqueSeparator'),
},
// Link Color
{label: 'linkColor', color: PlatformColor('linkColor')},
{label: 'link', color: PlatformColor('link')},
// Nonadaptable Colors
{label: 'darkTextColor', color: PlatformColor('darkTextColor')},
{label: 'lightTextColor', color: PlatformColor('lightTextColor')},
{label: 'darkText', color: PlatformColor('darkText')},
{label: 'lightText', color: PlatformColor('lightText')},
// https://developer.apple.com/documentation/uikit/uicolor/standard_colors
// Adaptable Colors
{label: 'systemBlueColor', color: PlatformColor('systemBlueColor')},
{label: 'systemBrownColor', color: PlatformColor('systemBrownColor')},
{label: 'systemGreenColor', color: PlatformColor('systemGreenColor')},
{label: 'systemIndigoColor', color: PlatformColor('systemIndigoColor')},
{label: 'systemOrangeColor', color: PlatformColor('systemOrangeColor')},
{label: 'systemPinkColor', color: PlatformColor('systemPinkColor')},
{label: 'systemPurpleColor', color: PlatformColor('systemPurpleColor')},
{label: 'systemRedColor', color: PlatformColor('systemRedColor')},
{label: 'systemTealColor', color: PlatformColor('systemTealColor')},
{label: 'systemYellowColor', color: PlatformColor('systemYellowColor')},
{label: 'systemBlue', color: PlatformColor('systemBlue')},
{label: 'systemBrown', color: PlatformColor('systemBrown')},
{label: 'systemGreen', color: PlatformColor('systemGreen')},
{label: 'systemIndigo', color: PlatformColor('systemIndigo')},
{label: 'systemOrange', color: PlatformColor('systemOrange')},
{label: 'systemPink', color: PlatformColor('systemPink')},
{label: 'systemPurple', color: PlatformColor('systemPurple')},
{label: 'systemRed', color: PlatformColor('systemRed')},
{label: 'systemTeal', color: PlatformColor('systemTeal')},
{label: 'systemYellow', color: PlatformColor('systemYellow')},
// Adaptable Gray Colors
{label: 'systemGrayColor', color: PlatformColor('systemGrayColor')},
{label: 'systemGray2Color', color: PlatformColor('systemGray2Color')},
{label: 'systemGray3Color', color: PlatformColor('systemGray3Color')},
{label: 'systemGray4Color', color: PlatformColor('systemGray4Color')},
{label: 'systemGray5Color', color: PlatformColor('systemGray5Color')},
{label: 'systemGray6Color', color: PlatformColor('systemGray6Color')},
{label: 'systemGray', color: PlatformColor('systemGray')},
{label: 'systemGray2', color: PlatformColor('systemGray2')},
{label: 'systemGray3', color: PlatformColor('systemGray3')},
{label: 'systemGray4', color: PlatformColor('systemGray4')},
{label: 'systemGray5', color: PlatformColor('systemGray5')},
{label: 'systemGray6', color: PlatformColor('systemGray6')},
];
} else if (Platform.OS === 'android') {
colors = [

Просмотреть файл

@ -604,7 +604,7 @@ static NSDictionary<NSString *, NSDictionary *> *RCTSemanticColorsMap()
{
static NSDictionary<NSString *, NSDictionary *> *colorMap = nil;
if (colorMap == nil) {
colorMap = @{
NSMutableDictionary<NSString *, NSDictionary *> *map = [@{
// https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors
// Label Colors
@"labelColor" : @{
@ -729,7 +729,22 @@ static NSDictionary<NSString *, NSDictionary *> *RCTSemanticColorsMap()
// iOS 13.0
RCTFallbackARGB : @(0xFFf2f2f7)
},
} mutableCopy];
// The color names are the Objective-C UIColor selector names,
// but Swift selector names are valid as well, so make aliases.
static NSString *const RCTColorSuffix = @"Color";
NSMutableDictionary<NSString *, NSDictionary *> *aliases = [NSMutableDictionary new];
for (NSString *objcSelector in map) {
RCTAssert([objcSelector hasSuffix:RCTColorSuffix], @"A selector in the color map did not end with the suffix Color.");
NSMutableDictionary *entry = [map[objcSelector] mutableCopy];
RCTAssert([entry objectForKey:RCTSelector] == nil, @"Entry should not already have an RCTSelector");
NSString *swiftSelector = [objcSelector substringToIndex:[objcSelector length] - [RCTColorSuffix length]];
entry[RCTSelector] = objcSelector;
aliases[swiftSelector] = entry;
}
[map addEntriesFromDictionary:aliases];
#if DEBUG
[map addEntriesFromDictionary:@{
// The follow exist for Unit Tests
@"unitTestFallbackColor" : @{RCTFallback : @"gridColor"},
@"unitTestFallbackColorIOS" : @{RCTFallback : @"blueColor"},
@ -743,9 +758,11 @@ static NSDictionary<NSString *, NSDictionary *> *RCTSemanticColorsMap()
RCTIndex : @1,
RCTFallback : @"controlAlternatingRowBackgroundColors"
},
}];
#endif
};
colorMap = [map copy];
}
return colorMap;
}