Skip to content

Commit

Permalink
Allow PlatformColor to work with RCTView border colors (#29728)
Browse files Browse the repository at this point in the history
Summary:
# See PR
#29728

# From PR Author
Using `PlatformColor` with border colors doesn't work currently when switching dark mode as the information is lost when converting to `CGColor`. This change keeps the border colors around as `UIColor` so switching to dark mode works.

```ts
<View
  style={{
    borderColor: DynamicColorIOS({ dark: "yellow", light: "red" }),
    borderWidth: 1,
  }}
>
...
</View>
```
This view will start with a red border (assuming light mode when started), but will not change to a yellow border when switching to dark mode. With this PR, the border color will be correctly set to yellow.

## Changelog

[iOS] [Fixed] - Allow PlatformColor to work with border colors

Pull Request resolved: #29728

Test Plan:
1. Assign a `PlatformColor` or `DynamicColorIOS` to a view border color.
2. Toggle between dark / light mode. See the colors change.

Reviewed By: lunaleaps

Differential Revision: D29268376

Pulled By: p-sun

fbshipit-source-id: 586545b05be0beb0e6e5ace6e3f74b304620ad94
  • Loading branch information
danilobuerger authored and facebook-github-bot committed Jun 23, 2021
1 parent 123d184 commit c974cbf
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 51 deletions.
14 changes: 7 additions & 7 deletions React/Views/RCTView.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
/**
* Border colors (actually retained).
*/
@property (nonatomic, assign) CGColorRef borderTopColor;
@property (nonatomic, assign) CGColorRef borderRightColor;
@property (nonatomic, assign) CGColorRef borderBottomColor;
@property (nonatomic, assign) CGColorRef borderLeftColor;
@property (nonatomic, assign) CGColorRef borderStartColor;
@property (nonatomic, assign) CGColorRef borderEndColor;
@property (nonatomic, assign) CGColorRef borderColor;
@property (nonatomic, strong) UIColor *borderTopColor;
@property (nonatomic, strong) UIColor *borderRightColor;
@property (nonatomic, strong) UIColor *borderBottomColor;
@property (nonatomic, strong) UIColor *borderLeftColor;
@property (nonatomic, strong) UIColor *borderStartColor;
@property (nonatomic, strong) UIColor *borderEndColor;
@property (nonatomic, strong) UIColor *borderColor;

/**
* Border widths.
Expand Down
72 changes: 30 additions & 42 deletions React/Views/RCTView.m
Original file line number Diff line number Diff line change
Expand Up @@ -729,28 +729,28 @@ - (RCTBorderColors)borderColors
const BOOL isRTL = _reactLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft;

if ([[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]) {
const CGColorRef borderStartColor = _borderStartColor ?: _borderLeftColor;
const CGColorRef borderEndColor = _borderEndColor ?: _borderRightColor;
UIColor *borderStartColor = _borderStartColor ?: _borderLeftColor;
UIColor *borderEndColor = _borderEndColor ?: _borderRightColor;

const CGColorRef directionAwareBorderLeftColor = isRTL ? borderEndColor : borderStartColor;
const CGColorRef directionAwareBorderRightColor = isRTL ? borderStartColor : borderEndColor;
UIColor *directionAwareBorderLeftColor = isRTL ? borderEndColor : borderStartColor;
UIColor *directionAwareBorderRightColor = isRTL ? borderStartColor : borderEndColor;

return (RCTBorderColors){
_borderTopColor ?: _borderColor,
directionAwareBorderLeftColor ?: _borderColor,
_borderBottomColor ?: _borderColor,
directionAwareBorderRightColor ?: _borderColor,
(_borderTopColor ?: _borderColor).CGColor,
(directionAwareBorderLeftColor ?: _borderColor).CGColor,
(_borderBottomColor ?: _borderColor).CGColor,
(directionAwareBorderRightColor ?: _borderColor).CGColor,
};
}

const CGColorRef directionAwareBorderLeftColor = isRTL ? _borderEndColor : _borderStartColor;
const CGColorRef directionAwareBorderRightColor = isRTL ? _borderStartColor : _borderEndColor;
UIColor *directionAwareBorderLeftColor = isRTL ? _borderEndColor : _borderStartColor;
UIColor *directionAwareBorderRightColor = isRTL ? _borderStartColor : _borderEndColor;

return (RCTBorderColors){
_borderTopColor ?: _borderColor,
directionAwareBorderLeftColor ?: _borderLeftColor ?: _borderColor,
_borderBottomColor ?: _borderColor,
directionAwareBorderRightColor ?: _borderRightColor ?: _borderColor,
(_borderTopColor ?: _borderColor).CGColor,
(directionAwareBorderLeftColor ?: _borderLeftColor ?: _borderColor).CGColor,
(_borderBottomColor ?: _borderColor).CGColor,
(directionAwareBorderRightColor ?: _borderRightColor ?: _borderColor).CGColor,
};
}

Expand Down Expand Up @@ -902,19 +902,18 @@ - (void)updateClippingForLayer:(CALayer *)layer

#pragma mark Border Color

#define setBorderColor(side) \
-(void)setBorder##side##Color : (CGColorRef)color \
{ \
if (CGColorEqualToColor(_border##side##Color, color)) { \
return; \
} \
CGColorRelease(_border##side##Color); \
_border##side##Color = CGColorRetain(color); \
[self.layer setNeedsDisplay]; \
#define setBorderColor(side) \
-(void)setBorder##side##Color : (UIColor *)color \
{ \
if ([_border##side##Color isEqual:color]) { \
return; \
} \
_border##side##Color = color; \
[self.layer setNeedsDisplay]; \
}

setBorderColor() setBorderColor(Top) setBorderColor(Right) setBorderColor(Bottom) setBorderColor(Left)
setBorderColor(Start) setBorderColor(End)
setBorderColor(Start) setBorderColor(End)

#pragma mark - Border Width

Expand All @@ -928,8 +927,8 @@ -(void)setBorder##side##Width : (CGFloat)width \
[self.layer setNeedsDisplay]; \
}

setBorderWidth() setBorderWidth(Top) setBorderWidth(Right) setBorderWidth(Bottom) setBorderWidth(Left)
setBorderWidth(Start) setBorderWidth(End)
setBorderWidth() setBorderWidth(Top) setBorderWidth(Right) setBorderWidth(Bottom) setBorderWidth(Left)
setBorderWidth(Start) setBorderWidth(End)

#pragma mark - Border Radius

Expand All @@ -943,9 +942,9 @@ -(void)setBorder##side##Radius : (CGFloat)radius \
[self.layer setNeedsDisplay]; \
}

setBorderRadius() setBorderRadius(TopLeft) setBorderRadius(TopRight) setBorderRadius(TopStart)
setBorderRadius(TopEnd) setBorderRadius(BottomLeft) setBorderRadius(BottomRight)
setBorderRadius(BottomStart) setBorderRadius(BottomEnd)
setBorderRadius() setBorderRadius(TopLeft) setBorderRadius(TopRight) setBorderRadius(TopStart)
setBorderRadius(TopEnd) setBorderRadius(BottomLeft) setBorderRadius(BottomRight)
setBorderRadius(BottomStart) setBorderRadius(BottomEnd)

#pragma mark - Border Style

Expand All @@ -959,17 +958,6 @@ -(void)setBorder##side##Style : (RCTBorderStyle)style \
[self.layer setNeedsDisplay]; \
}

setBorderStyle()
setBorderStyle()

- (void)dealloc
{
CGColorRelease(_borderColor);
CGColorRelease(_borderTopColor);
CGColorRelease(_borderRightColor);
CGColorRelease(_borderBottomColor);
CGColorRelease(_borderLeftColor);
CGColorRelease(_borderStartColor);
CGColorRelease(_borderEndColor);
}

@end
@end
4 changes: 2 additions & 2 deletions React/Views/RCTViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ - (RCTShadowView *)shadowView
RCT_CUSTOM_VIEW_PROPERTY(borderColor, CGColor, RCTView)
{
if ([view respondsToSelector:@selector(setBorderColor:)]) {
view.borderColor = json ? [RCTConvert CGColor:json] : defaultView.borderColor;
view.borderColor = json ? [RCTConvert UIColor:json] : defaultView.borderColor;
} else {
view.layer.borderColor = json ? [RCTConvert CGColor:json] : defaultView.layer.borderColor;
}
Expand Down Expand Up @@ -318,7 +318,7 @@ - (RCTShadowView *)shadowView
RCT_CUSTOM_VIEW_PROPERTY(border##SIDE##Color, UIColor, RCTView) \
{ \
if ([view respondsToSelector:@selector(setBorder##SIDE##Color:)]) { \
view.border##SIDE##Color = json ? [RCTConvert CGColor:json] : defaultView.border##SIDE##Color; \
view.border##SIDE##Color = json ? [RCTConvert UIColor:json] : defaultView.border##SIDE##Color; \
} \
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,20 @@ function DynamicColorsExample() {
}}
/>
</View>
<View style={styles.row}>
<Text style={styles.labelCell}>
DynamicColorIOS({'{\n'}
{' '}light: 'red', dark: 'blue'{'\n'}
{'}'})
</Text>
<View
style={{
...styles.colorCell,
borderColor: DynamicColorIOS({light: 'red', dark: 'blue'}),
borderWidth: 1,
}}
/>
</View>
<View style={styles.row}>
<Text style={styles.labelCell}>
DynamicColorIOS({'{\n'}
Expand Down

0 comments on commit c974cbf

Please sign in to comment.