From e5dbf079bc27e8103e0f03afb7a52e1df58aeb87 Mon Sep 17 00:00:00 2001 From: Rahul Malik Date: Fri, 19 Jul 2019 19:18:05 -0700 Subject: [PATCH] Update Pending state type for backgroundColor to UIColor to avoid losing its new dynamic capabilties (#1592) --- Source/Details/UIView+ASConvenience.h | 2 +- Source/Private/ASDisplayNode+UIViewBridge.mm | 13 ++++--- Source/Private/_ASPendingState.mm | 36 ++++++++++---------- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/Source/Details/UIView+ASConvenience.h b/Source/Details/UIView+ASConvenience.h index 19fd57695..7d34340b3 100644 --- a/Source/Details/UIView+ASConvenience.h +++ b/Source/Details/UIView+ASConvenience.h @@ -39,7 +39,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) CGFloat borderWidth; @property (nonatomic, getter = isOpaque) BOOL opaque; @property (nonatomic) __attribute__((NSObject)) CGColorRef borderColor; -@property (nonatomic) __attribute__((NSObject)) CGColorRef backgroundColor; +@property (nonatomic) UIColor *backgroundColor; @property (nonatomic) BOOL allowsGroupOpacity; @property (nonatomic) BOOL allowsEdgeAntialiasing; @property (nonatomic) unsigned int edgeAntialiasingMask; diff --git a/Source/Private/ASDisplayNode+UIViewBridge.mm b/Source/Private/ASDisplayNode+UIViewBridge.mm index 0aef83fc4..108f69077 100644 --- a/Source/Private/ASDisplayNode+UIViewBridge.mm +++ b/Source/Private/ASDisplayNode+UIViewBridge.mm @@ -750,24 +750,23 @@ - (UIColor *)backgroundColor if (!_flags.layerBacked) { return _view.backgroundColor; } else { - return [UIColor colorWithCGColor:_getFromLayer(backgroundColor)]; + return [UIColor colorWithCGColor:_layer.backgroundColor]; } } - return [UIColor colorWithCGColor:ASDisplayNodeGetPendingState(self).backgroundColor]; + return ASDisplayNodeGetPendingState(self).backgroundColor; } - (void)setBackgroundColor:(UIColor *)newBackgroundColor { _bridge_prologue_write; - - BOOL shouldApply = ASDisplayNodeShouldApplyBridgedWriteToView(self); - CGColorRef newBackgroundCGColor = newBackgroundColor.CGColor; + CGColorRef newBackgroundCGColor = nil; if (shouldApply) { CGColorRef oldBackgroundCGColor = _layer.backgroundColor; if (_flags.layerBacked) { _layer.backgroundColor = newBackgroundColor.CGColor; + newBackgroundCGColor = _layer.backgroundColor; } else { /* NOTE: Setting to the view and layer individually is necessary. @@ -778,9 +777,9 @@ - (void)setBackgroundColor:(UIColor *)newBackgroundColor */ _view.backgroundColor = newBackgroundColor; - _layer.backgroundColor = _view.backgroundColor.CGColor; // Gather the CGColorRef from the view incase there are any changes it might apply to which CGColorRef is returned for dynamic colors newBackgroundCGColor = _view.backgroundColor.CGColor; + _layer.backgroundColor = newBackgroundCGColor; } if (!CGColorEqualToColor(oldBackgroundCGColor, newBackgroundCGColor)) { @@ -790,7 +789,7 @@ - (void)setBackgroundColor:(UIColor *)newBackgroundColor // NOTE: If we're in the background, we cannot read the current value of bgcolor (if loaded). // When the pending state is applied to the view on main, we will call `setNeedsDisplay` if // the new background color doesn't match the one on the layer. - ASDisplayNodeGetPendingState(self).backgroundColor = newBackgroundCGColor; + ASDisplayNodeGetPendingState(self).backgroundColor = newBackgroundColor; } } diff --git a/Source/Private/_ASPendingState.mm b/Source/Private/_ASPendingState.mm index 2663955a5..6922f6a2b 100644 --- a/Source/Private/_ASPendingState.mm +++ b/Source/Private/_ASPendingState.mm @@ -16,9 +16,13 @@ #import #import -#define __shouldSetNeedsDisplay(layer) (flags.needsDisplay \ +#define __shouldSetNeedsDisplayForView(view) (flags.needsDisplay \ + || (flags.setOpaque && _flags.opaque != (view).opaque)\ + || (flags.setBackgroundColor && ![backgroundColor isEqual:(view).backgroundColor])) + +#define __shouldSetNeedsDisplayForLayer(layer) (flags.needsDisplay \ || (flags.setOpaque && _flags.opaque != (layer).opaque)\ - || (flags.setBackgroundColor && !CGColorEqualToColor(backgroundColor, (layer).backgroundColor))) + || (flags.setBackgroundColor && ![backgroundColor isEqual:[UIColor colorWithCGColor:(layer).backgroundColor]])) typedef struct { // Properties @@ -102,7 +106,7 @@ @implementation _ASPendingState unsigned int edgeAntialiasingMask; CGRect frame; // Frame is only to be used for synchronous views wrapped by nodes (see setFrame:) CGRect bounds; - CGColorRef backgroundColor; + UIColor *backgroundColor; CGFloat alpha; CGFloat cornerRadius; UIViewContentMode contentMode; @@ -415,19 +419,17 @@ - (void)setBounds:(CGRect)newBounds _stateToApplyFlags.setBounds = YES; } -- (CGColorRef)backgroundColor +- (UIColor *)backgroundColor { return backgroundColor; } -- (void)setBackgroundColor:(CGColorRef)color +- (void)setBackgroundColor:(UIColor *)color { - if (color == backgroundColor) { + if ([color isEqual:backgroundColor]) { return; } - - CGColorRelease(backgroundColor); - backgroundColor = CGColorRetain(color); + backgroundColor = color; _stateToApplyFlags.setBackgroundColor = YES; } @@ -926,7 +928,7 @@ - (void)applyToLayer:(CALayer *)layer { ASPendingStateFlags flags = _stateToApplyFlags; - if (__shouldSetNeedsDisplay(layer)) { + if (__shouldSetNeedsDisplayForLayer(layer)) { [layer setNeedsDisplay]; } @@ -964,7 +966,7 @@ - (void)applyToLayer:(CALayer *)layer layer.masksToBounds = _flags.clipsToBounds; if (flags.setBackgroundColor) - layer.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; if (flags.setOpaque) layer.opaque = _flags.opaque; @@ -1048,7 +1050,7 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr unowned CALayer *layer = view.layer; ASPendingStateFlags flags = _stateToApplyFlags; - if (__shouldSetNeedsDisplay(layer)) { + if (__shouldSetNeedsDisplayForView(view)) { [view setNeedsDisplay]; } @@ -1095,8 +1097,8 @@ - (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPr view.clipsToBounds = _flags.clipsToBounds; if (flags.setBackgroundColor) { - view.backgroundColor = [UIColor colorWithCGColor:backgroundColor]; - layer.backgroundColor = backgroundColor; + view.backgroundColor = backgroundColor; + layer.backgroundColor = backgroundColor.CGColor; } if (flags.setTintColor) @@ -1286,7 +1288,7 @@ + (_ASPendingState *)pendingViewStateFromLayer:(CALayer *)layer pendingState.contentsScale = layer.contentsScale; pendingState.rasterizationScale = layer.rasterizationScale; pendingState.clipsToBounds = layer.masksToBounds; - pendingState.backgroundColor = layer.backgroundColor; + pendingState.backgroundColor = [UIColor colorWithCGColor:layer.backgroundColor]; pendingState.opaque = layer.opaque; pendingState.hidden = layer.hidden; pendingState.alpha = layer.opacity; @@ -1327,7 +1329,7 @@ + (_ASPendingState *)pendingViewStateFromView:(UIView *)view pendingState.contentsScale = layer.contentsScale; pendingState.rasterizationScale = layer.rasterizationScale; pendingState.clipsToBounds = view.clipsToBounds; - pendingState.backgroundColor = layer.backgroundColor; + pendingState.backgroundColor = [UIColor colorWithCGColor:layer.backgroundColor]; pendingState.tintColor = view.tintColor; pendingState.opaque = layer.opaque; pendingState.hidden = view.hidden; @@ -1404,8 +1406,6 @@ - (BOOL)hasChanges - (void)dealloc { - CGColorRelease(backgroundColor); - if (shadowColor != blackColorRef) { CGColorRelease(shadowColor); }