mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Back out "fix(iOS): Replace uses of CGColorRef with UIColor to avoid manual memory management" (#46967)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46967 Original commit changeset: 5e85e17567e3 Original Phabricator Diff: D63989547 This is causing some crashes internally Changelog: [Internal] Reviewed By: shwanton Differential Revision: D64194385 fbshipit-source-id: 835469e09971ae39d2db6e82f6c05970b1e6238c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f25abe51ce
commit
b0e2cb3371
+30
-15
@@ -242,8 +242,9 @@ const CGFloat BACKGROUND_COLOR_ZPOSITION = -1024.0f;
|
||||
|
||||
// `shadowColor`
|
||||
if (oldViewProps.shadowColor != newViewProps.shadowColor) {
|
||||
UIColor *shadowColor = RCTUIColorFromSharedColor(newViewProps.shadowColor);
|
||||
self.layer.shadowColor = shadowColor.CGColor;
|
||||
CGColorRef shadowColor = RCTCreateCGColorRefFromSharedColor(newViewProps.shadowColor);
|
||||
self.layer.shadowColor = shadowColor;
|
||||
CGColorRelease(shadowColor);
|
||||
needsInvalidateLayer = YES;
|
||||
}
|
||||
|
||||
@@ -681,7 +682,7 @@ static void RCTAddContourEffectToLayer(
|
||||
const RCTBorderStyle &contourStyle)
|
||||
{
|
||||
UIImage *image = RCTGetBorderImage(
|
||||
contourStyle, layer.bounds.size, cornerRadii, contourInsets, contourColors, [UIColor clearColor], NO);
|
||||
contourStyle, layer.bounds.size, cornerRadii, contourInsets, contourColors, [UIColor clearColor].CGColor, NO);
|
||||
|
||||
if (image == nil) {
|
||||
layer.contents = nil;
|
||||
@@ -710,10 +711,18 @@ static void RCTAddContourEffectToLayer(
|
||||
static RCTBorderColors RCTCreateRCTBorderColorsFromBorderColors(BorderColors borderColors)
|
||||
{
|
||||
return RCTBorderColors{
|
||||
.top = RCTUIColorFromSharedColor(borderColors.top),
|
||||
.left = RCTUIColorFromSharedColor(borderColors.left),
|
||||
.bottom = RCTUIColorFromSharedColor(borderColors.bottom),
|
||||
.right = RCTUIColorFromSharedColor(borderColors.right)};
|
||||
.top = RCTCreateCGColorRefFromSharedColor(borderColors.top),
|
||||
.left = RCTCreateCGColorRefFromSharedColor(borderColors.left),
|
||||
.bottom = RCTCreateCGColorRefFromSharedColor(borderColors.bottom),
|
||||
.right = RCTCreateCGColorRefFromSharedColor(borderColors.right)};
|
||||
}
|
||||
|
||||
static void RCTReleaseRCTBorderColors(RCTBorderColors borderColors)
|
||||
{
|
||||
CGColorRelease(borderColors.top);
|
||||
CGColorRelease(borderColors.left);
|
||||
CGColorRelease(borderColors.bottom);
|
||||
CGColorRelease(borderColors.right);
|
||||
}
|
||||
|
||||
static CALayerCornerCurve CornerCurveFromBorderCurve(BorderCurve borderCurve)
|
||||
@@ -861,7 +870,7 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
|
||||
(*borderMetrics.borderColors.left).getUIColor() != nullptr));
|
||||
|
||||
// background color
|
||||
UIColor *backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection];
|
||||
CGColorRef backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor;
|
||||
// The reason we sometimes do not set self.layer's backgroundColor is because
|
||||
// we want to support non-uniform border radii, which apple does not natively
|
||||
// support. To get this behavior we need to create a CGPath in the shape that
|
||||
@@ -871,7 +880,7 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
|
||||
if (useCoreAnimationBorderRendering) {
|
||||
[_backgroundColorLayer removeFromSuperlayer];
|
||||
_backgroundColorLayer = nil;
|
||||
layer.backgroundColor = backgroundColor.CGColor;
|
||||
layer.backgroundColor = backgroundColor;
|
||||
} else {
|
||||
layer.backgroundColor = nil;
|
||||
if (!_backgroundColorLayer) {
|
||||
@@ -881,7 +890,7 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
|
||||
[self.layer addSublayer:_backgroundColorLayer];
|
||||
}
|
||||
|
||||
_backgroundColorLayer.backgroundColor = backgroundColor.CGColor;
|
||||
_backgroundColorLayer.backgroundColor = backgroundColor;
|
||||
if (borderMetrics.borderRadii.isUniform()) {
|
||||
_backgroundColorLayer.mask = nil;
|
||||
_backgroundColorLayer.cornerRadius = borderMetrics.borderRadii.topLeft.horizontal;
|
||||
@@ -902,8 +911,9 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
|
||||
_borderLayer = nil;
|
||||
|
||||
layer.borderWidth = (CGFloat)borderMetrics.borderWidths.left;
|
||||
UIColor *borderColor = RCTUIColorFromSharedColor(borderMetrics.borderColors.left);
|
||||
layer.borderColor = borderColor.CGColor;
|
||||
CGColorRef borderColor = RCTCreateCGColorRefFromSharedColor(borderMetrics.borderColors.left);
|
||||
layer.borderColor = borderColor;
|
||||
CGColorRelease(borderColor);
|
||||
layer.cornerRadius = (CGFloat)borderMetrics.borderRadii.topLeft.horizontal;
|
||||
layer.cornerCurve = CornerCurveFromBorderCurve(borderMetrics.borderCurves.topLeft);
|
||||
} else {
|
||||
@@ -928,6 +938,8 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
|
||||
borderColors,
|
||||
RCTUIEdgeInsetsFromEdgeInsets(borderMetrics.borderWidths),
|
||||
RCTBorderStyleFromBorderStyle(borderMetrics.borderStyles.left));
|
||||
|
||||
RCTReleaseRCTBorderColors(borderColors);
|
||||
}
|
||||
|
||||
// outline
|
||||
@@ -946,11 +958,12 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
|
||||
layer.bounds, -_props->outlineOffset - _props->outlineWidth, -_props->outlineOffset - _props->outlineWidth);
|
||||
|
||||
if (borderMetrics.borderRadii.isUniform() && borderMetrics.borderRadii.topLeft.horizontal == 0) {
|
||||
UIColor *outlineColor = RCTUIColorFromSharedColor(_props->outlineColor);
|
||||
CGColorRef outlineColor = RCTCreateCGColorRefFromSharedColor(_props->outlineColor);
|
||||
_outlineLayer.borderWidth = _props->outlineWidth;
|
||||
_outlineLayer.borderColor = outlineColor.CGColor;
|
||||
_outlineLayer.borderColor = outlineColor;
|
||||
CGColorRelease(outlineColor);
|
||||
} else {
|
||||
UIColor *outlineColor = RCTUIColorFromSharedColor(_props->outlineColor);
|
||||
CGColorRef outlineColor = RCTCreateCGColorRefFromSharedColor(_props->outlineColor);
|
||||
|
||||
RCTAddContourEffectToLayer(
|
||||
_outlineLayer,
|
||||
@@ -958,6 +971,8 @@ static RCTBorderStyle RCTBorderStyleFromOutlineStyle(OutlineStyle outlineStyle)
|
||||
RCTBorderColors{outlineColor, outlineColor, outlineColor, outlineColor},
|
||||
UIEdgeInsets{_props->outlineWidth, _props->outlineWidth, _props->outlineWidth, _props->outlineWidth},
|
||||
RCTBorderStyleFromOutlineStyle(_props->outlineStyle));
|
||||
|
||||
CGColorRelease(outlineColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,12 @@ inline UIColor *_Nullable RCTUIColorFromSharedColor(const facebook::react::Share
|
||||
return RCTPlatformColorFromColor(*sharedColor);
|
||||
}
|
||||
|
||||
inline CF_RETURNS_RETAINED CGColorRef _Nullable RCTCreateCGColorRefFromSharedColor(
|
||||
const facebook::react::SharedColor &sharedColor)
|
||||
{
|
||||
return CGColorRetain(RCTUIColorFromSharedColor(sharedColor).CGColor);
|
||||
}
|
||||
|
||||
inline CGPoint RCTCGPointFromPoint(const facebook::react::Point &point)
|
||||
{
|
||||
return {point.x, point.y};
|
||||
|
||||
@@ -29,10 +29,10 @@ typedef struct {
|
||||
} RCTCornerInsets;
|
||||
|
||||
typedef struct {
|
||||
UIColor *top;
|
||||
UIColor *left;
|
||||
UIColor *bottom;
|
||||
UIColor *right;
|
||||
CGColorRef top;
|
||||
CGColorRef left;
|
||||
CGColorRef bottom;
|
||||
CGColorRef right;
|
||||
} RCTBorderColors;
|
||||
|
||||
/**
|
||||
@@ -67,5 +67,5 @@ RCT_EXTERN UIImage *RCTGetBorderImage(
|
||||
RCTCornerRadii cornerRadii,
|
||||
UIEdgeInsets borderInsets,
|
||||
RCTBorderColors borderColors,
|
||||
UIColor *backgroundColor,
|
||||
CGColorRef backgroundColor,
|
||||
BOOL drawToEdge);
|
||||
|
||||
@@ -30,9 +30,9 @@ BOOL RCTCornerRadiiAreEqualAndSymmetrical(RCTCornerRadii cornerRadii)
|
||||
|
||||
BOOL RCTBorderColorsAreEqual(RCTBorderColors borderColors)
|
||||
{
|
||||
return CGColorEqualToColor(borderColors.left.CGColor, borderColors.right.CGColor) &&
|
||||
CGColorEqualToColor(borderColors.left.CGColor, borderColors.top.CGColor) &&
|
||||
CGColorEqualToColor(borderColors.left.CGColor, borderColors.bottom.CGColor);
|
||||
return CGColorEqualToColor(borderColors.left, borderColors.right) &&
|
||||
CGColorEqualToColor(borderColors.left, borderColors.top) &&
|
||||
CGColorEqualToColor(borderColors.left, borderColors.bottom);
|
||||
}
|
||||
|
||||
RCTCornerInsets RCTGetCornerInsets(RCTCornerRadii cornerRadii, UIEdgeInsets edgeInsets)
|
||||
@@ -182,9 +182,9 @@ static CGPathRef RCTPathCreateOuterOutline(BOOL drawToEdge, CGRect rect, RCTCorn
|
||||
}
|
||||
|
||||
static UIGraphicsImageRenderer *
|
||||
RCTMakeUIGraphicsImageRenderer(CGSize size, UIColor *backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge)
|
||||
RCTMakeUIGraphicsImageRenderer(CGSize size, CGColorRef backgroundColor, BOOL hasCornerRadii, BOOL drawToEdge)
|
||||
{
|
||||
const CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor);
|
||||
const CGFloat alpha = CGColorGetAlpha(backgroundColor);
|
||||
const BOOL opaque = (drawToEdge || !hasCornerRadii) && alpha == 1.0;
|
||||
UIGraphicsImageRendererFormat *const rendererFormat = [UIGraphicsImageRendererFormat defaultFormat];
|
||||
rendererFormat.opaque = opaque;
|
||||
@@ -197,7 +197,7 @@ static UIImage *RCTGetSolidBorderImage(
|
||||
CGSize viewSize,
|
||||
UIEdgeInsets borderInsets,
|
||||
RCTBorderColors borderColors,
|
||||
UIColor *backgroundColor,
|
||||
CGColorRef backgroundColor,
|
||||
BOOL drawToEdge)
|
||||
{
|
||||
const BOOL hasCornerRadii = RCTCornerRadiiAreAboveThreshold(cornerRadii);
|
||||
@@ -233,16 +233,18 @@ static UIImage *RCTGetSolidBorderImage(
|
||||
UIGraphicsImageRenderer *const imageRenderer =
|
||||
RCTMakeUIGraphicsImageRenderer(size, backgroundColor, hasCornerRadii, drawToEdge);
|
||||
|
||||
CGColorRetain(backgroundColor);
|
||||
UIImage *image = [imageRenderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull rendererContext) {
|
||||
const CGContextRef context = rendererContext.CGContext;
|
||||
const CGRect rect = {.size = size};
|
||||
CGPathRef path = RCTPathCreateOuterOutline(drawToEdge, rect, cornerRadii);
|
||||
|
||||
if (backgroundColor) {
|
||||
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
|
||||
CGContextSetFillColorWithColor(context, backgroundColor);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
CGColorRelease(backgroundColor);
|
||||
|
||||
CGContextAddPath(context, path);
|
||||
CGPathRelease(path);
|
||||
@@ -254,7 +256,7 @@ static UIImage *RCTGetSolidBorderImage(
|
||||
|
||||
BOOL hasEqualColors = RCTBorderColorsAreEqual(borderColors);
|
||||
if ((drawToEdge || !hasCornerRadii) && hasEqualColors) {
|
||||
CGContextSetFillColorWithColor(context, borderColors.left.CGColor);
|
||||
CGContextSetFillColorWithColor(context, borderColors.left);
|
||||
CGContextAddRect(context, rect);
|
||||
CGContextAddPath(context, insetPath);
|
||||
CGContextEOFillPath(context);
|
||||
@@ -319,7 +321,7 @@ static UIImage *RCTGetSolidBorderImage(
|
||||
}
|
||||
}
|
||||
|
||||
UIColor *currentColor = nil;
|
||||
CGColorRef currentColor = NULL;
|
||||
|
||||
// RIGHT
|
||||
if (borderInsets.right > 0) {
|
||||
@@ -343,8 +345,8 @@ static UIImage *RCTGetSolidBorderImage(
|
||||
(CGPoint){size.width, size.height},
|
||||
};
|
||||
|
||||
if (!CGColorEqualToColor(currentColor.CGColor, borderColors.bottom.CGColor)) {
|
||||
CGContextSetFillColorWithColor(context, currentColor.CGColor);
|
||||
if (!CGColorEqualToColor(currentColor, borderColors.bottom)) {
|
||||
CGContextSetFillColorWithColor(context, currentColor);
|
||||
CGContextFillPath(context);
|
||||
currentColor = borderColors.bottom;
|
||||
}
|
||||
@@ -360,8 +362,8 @@ static UIImage *RCTGetSolidBorderImage(
|
||||
(CGPoint){0, size.height},
|
||||
};
|
||||
|
||||
if (!CGColorEqualToColor(currentColor.CGColor, borderColors.left.CGColor)) {
|
||||
CGContextSetFillColorWithColor(context, currentColor.CGColor);
|
||||
if (!CGColorEqualToColor(currentColor, borderColors.left)) {
|
||||
CGContextSetFillColorWithColor(context, currentColor);
|
||||
CGContextFillPath(context);
|
||||
currentColor = borderColors.left;
|
||||
}
|
||||
@@ -377,15 +379,15 @@ static UIImage *RCTGetSolidBorderImage(
|
||||
(CGPoint){size.width, 0},
|
||||
};
|
||||
|
||||
if (!CGColorEqualToColor(currentColor.CGColor, borderColors.top.CGColor)) {
|
||||
CGContextSetFillColorWithColor(context, currentColor.CGColor);
|
||||
if (!CGColorEqualToColor(currentColor, borderColors.top)) {
|
||||
CGContextSetFillColorWithColor(context, currentColor);
|
||||
CGContextFillPath(context);
|
||||
currentColor = borderColors.top;
|
||||
}
|
||||
CGContextAddLines(context, points, sizeof(points) / sizeof(*points));
|
||||
}
|
||||
|
||||
CGContextSetFillColorWithColor(context, currentColor.CGColor);
|
||||
CGContextSetFillColorWithColor(context, currentColor);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
|
||||
@@ -465,7 +467,7 @@ static UIImage *RCTGetDashedOrDottedBorderImage(
|
||||
CGSize viewSize,
|
||||
UIEdgeInsets borderInsets,
|
||||
RCTBorderColors borderColors,
|
||||
UIColor *backgroundColor,
|
||||
CGColorRef backgroundColor,
|
||||
BOOL drawToEdge)
|
||||
{
|
||||
NSCParameterAssert(borderStyle == RCTBorderStyleDashed || borderStyle == RCTBorderStyleDotted);
|
||||
@@ -492,7 +494,7 @@ static UIImage *RCTGetDashedOrDottedBorderImage(
|
||||
CGContextAddPath(context, outerPath);
|
||||
CGPathRelease(outerPath);
|
||||
|
||||
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
|
||||
CGContextSetFillColorWithColor(context, backgroundColor);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
|
||||
@@ -511,7 +513,7 @@ static UIImage *RCTGetDashedOrDottedBorderImage(
|
||||
CGContextSetStrokeColorWithColor(context, [UIColor yellowColor].CGColor);
|
||||
|
||||
CGContextAddPath(context, path);
|
||||
CGContextSetStrokeColorWithColor(context, borderColors.top.CGColor);
|
||||
CGContextSetStrokeColorWithColor(context, borderColors.top);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGPathRelease(path);
|
||||
@@ -524,7 +526,7 @@ UIImage *RCTGetBorderImage(
|
||||
RCTCornerRadii cornerRadii,
|
||||
UIEdgeInsets borderInsets,
|
||||
RCTBorderColors borderColors,
|
||||
UIColor *backgroundColor,
|
||||
CGColorRef backgroundColor,
|
||||
BOOL drawToEdge)
|
||||
{
|
||||
switch (borderStyle) {
|
||||
|
||||
@@ -774,10 +774,10 @@ static CGFloat RCTDefaultIfNegativeTo(CGFloat defaultValue, CGFloat x)
|
||||
[directionAwareBorderRightColor resolvedColorWithTraitCollection:self.traitCollection];
|
||||
|
||||
return (RCTBorderColors){
|
||||
(borderTopColor ?: borderColor),
|
||||
(directionAwareBorderLeftColor ?: borderColor),
|
||||
(borderBottomColor ?: borderColor),
|
||||
(directionAwareBorderRightColor ?: borderColor),
|
||||
(borderTopColor ?: borderColor).CGColor,
|
||||
(directionAwareBorderLeftColor ?: borderColor).CGColor,
|
||||
(borderBottomColor ?: borderColor).CGColor,
|
||||
(directionAwareBorderRightColor ?: borderColor).CGColor,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -814,20 +814,21 @@ static CGFloat RCTDefaultIfNegativeTo(CGFloat defaultValue, CGFloat x)
|
||||
// the content. For this reason, only use iOS border drawing when clipping
|
||||
// or when the border is hidden.
|
||||
|
||||
(borderInsets.top == 0 || (borderColors.top && CGColorGetAlpha(borderColors.top.CGColor) == 0) ||
|
||||
self.clipsToBounds);
|
||||
(borderInsets.top == 0 || (borderColors.top && CGColorGetAlpha(borderColors.top) == 0) || self.clipsToBounds);
|
||||
|
||||
// iOS clips to the outside of the border, but CSS clips to the inside. To
|
||||
// solve this, we'll need to add a container view inside the main view to
|
||||
// correctly clip the subviews.
|
||||
|
||||
UIColor *backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection];
|
||||
CGColorRef backgroundColor;
|
||||
|
||||
backgroundColor = [_backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor;
|
||||
|
||||
if (useIOSBorderRendering) {
|
||||
layer.cornerRadius = cornerRadii.topLeftHorizontal;
|
||||
layer.borderColor = borderColors.left.CGColor;
|
||||
layer.borderColor = borderColors.left;
|
||||
layer.borderWidth = borderInsets.left;
|
||||
layer.backgroundColor = backgroundColor.CGColor;
|
||||
layer.backgroundColor = backgroundColor;
|
||||
layer.contents = nil;
|
||||
layer.needsDisplayOnBoundsChange = NO;
|
||||
layer.mask = nil;
|
||||
|
||||
Reference in New Issue
Block a user