Merge pull request #1537 from maicki/FixASCollectionNodeASTableNodeBackgroundColor

Fix ASTableNode / ASCollectionNode backgroundColor does not apply correctly.
This commit is contained in:
appleguy
2016-04-19 12:30:54 -07:00
6 changed files with 33 additions and 11 deletions

View File

@@ -83,6 +83,13 @@ BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector)
return ASSubclassOverridesSelector([ASDisplayNode class], subclass, selector);
}
// For classes like ASTableNode, ASCollectionNode, ASScrollNode and similar - we have to be sure to set certain properties
// like setFrame: and setBackgroundColor: directly to the UIView and not apply it to the layer only.
BOOL ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(ASDisplayNodeFlags flags)
{
return flags.synchronous && !flags.layerBacked;
}
_ASPendingState *ASDisplayNodeGetPendingState(ASDisplayNode *node)
{
ASDN::MutexLocker l(node->_propertyLock);
@@ -954,8 +961,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
if (self.layerBacked) {
[_pendingViewState applyToLayer:self.layer];
} else {
BOOL setFrameDirectly = (_flags.synchronous && !_flags.layerBacked);
[_pendingViewState applyToView:self.view setFrameDirectly:setFrameDirectly];
BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(_flags);
[_pendingViewState applyToView:self.view withSpecialPropertiesHandling:specialPropertiesHandling];
}
[_pendingViewState clearChanges];

View File

@@ -20,7 +20,7 @@
@end
@interface ASTableNode ()
@property (nonatomic) _ASTablePendingState *pendingState;
@property (nonatomic, strong) _ASTablePendingState *pendingState;
@end
@interface ASTableView ()
@@ -68,7 +68,7 @@
ASTableView *view = self.view;
view.tableNode = self;
if (_pendingState) {
_ASTablePendingState *pendingState = _pendingState;
self.pendingState = nil;

View File

@@ -19,6 +19,7 @@
#import "ASPendingStateController.h"
#import "ASThread.h"
#import "ASTextNode.h"
#import "ASTableNode.h"
/**
* The following macros are conveniences to help in the common tasks related to the bridging that ASDisplayNode does to UIView and CALayer.
@@ -239,11 +240,11 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo
// For classes like ASTableNode, ASCollectionNode, ASScrollNode and similar - make sure UIView gets setFrame:
struct ASDisplayNodeFlags flags = _flags;
BOOL setFrameDirectly = flags.synchronous && !flags.layerBacked;
BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(flags);
BOOL nodeLoaded = __loaded(self);
BOOL isMainThread = ASDisplayNodeThreadIsMain();
if (!setFrameDirectly) {
if (!specialPropertiesHandling) {
BOOL canReadProperties = isMainThread || !nodeLoaded;
if (canReadProperties) {
// We don't have to set frame directly, and we can read current properties.
@@ -583,6 +584,12 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo
if (shouldApply) {
CGColorRef oldBackgroundCGColor = _layer.backgroundColor;
_layer.backgroundColor = newBackgroundCGColor;
BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(_flags);
if (specialPropertiesHandling) {
_view.backgroundColor = newBackgroundColor;
}
if (!CGColorEqualToColor(oldBackgroundCGColor, newBackgroundCGColor)) {
[self setNeedsDisplay];
}

View File

@@ -25,8 +25,10 @@
@class _ASDisplayLayer;
@class _ASPendingState;
@class ASSentinel;
struct ASDisplayNodeFlags;
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
BOOL ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(ASDisplayNodeFlags flags);
/// Get the pending view state for the node, creating one if needed.
_ASPendingState *ASDisplayNodeGetPendingState(ASDisplayNode *node);

View File

@@ -24,7 +24,7 @@
// Supports all of the properties included in the ASDisplayNodeViewProperties protocol
- (void)applyToView:(UIView *)view setFrameDirectly:(BOOL)setFrameDirectly;
- (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)setFrameDirectly;
- (void)applyToLayer:(CALayer *)layer;
+ (_ASPendingState *)pendingViewStateFromLayer:(CALayer *)layer;

View File

@@ -745,7 +745,7 @@ static UIColor *defaultTintColor = nil;
ASPendingStateApplyMetricsToLayer(self, layer);
}
- (void)applyToView:(UIView *)view setFrameDirectly:(BOOL)setFrameDirectly
- (void)applyToView:(UIView *)view withSpecialPropertiesHandling:(BOOL)specialPropertiesHandling
{
/*
Use our convenience setters blah here instead of layer.blah
@@ -789,9 +789,16 @@ static UIColor *defaultTintColor = nil;
if (flags.setClipsToBounds)
view.clipsToBounds = clipsToBounds;
if (flags.setBackgroundColor)
if (flags.setBackgroundColor) {
// Set the background color to the layer as in the UIView bridge we use this value as background color
layer.backgroundColor = backgroundColor;
// We have to make sure certain nodes get the background color call directly
if (specialPropertiesHandling) {
view.backgroundColor = [UIColor colorWithCGColor:backgroundColor];
}
}
if (flags.setTintColor)
view.tintColor = self.tintColor;
@@ -907,8 +914,7 @@ static UIColor *defaultTintColor = nil;
if (flags.setAccessibilityPath)
view.accessibilityPath = accessibilityPath;
// For classes like ASTableNode, ASCollectionNode, ASScrollNode and similar - make sure UIView gets setFrame:
if (flags.setFrame && setFrameDirectly) {
if (flags.setFrame && specialPropertiesHandling) {
// Frame is only defined when transform is identity because we explicitly diverge from CALayer behavior and define frame without transform
#if DEBUG
// Checking if the transform is identity is expensive, so disable when unnecessary. We have assertions on in Release, so DEBUG is the only way I know of.