mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Improve setting special properties for certain classes directly to the UIView
- Remove duplicated code in ASCollectionNode and ASTableNode - Fix setting the pending state to the view if applying the pending state to the view
This commit is contained in:
@@ -16,11 +16,6 @@
|
||||
@interface _ASCollectionPendingState : NSObject
|
||||
@property (weak, nonatomic) id <ASCollectionDelegate> delegate;
|
||||
@property (weak, nonatomic) id <ASCollectionDataSource> dataSource;
|
||||
|
||||
// If the background color is applied via the pending state it's applied to the layer of the UICollectionView.
|
||||
// Unfortunately UICollectionView does not consider using the layer backgroundColor property as it's background color,
|
||||
// so it needs to be applied to the view after the ASCollectionNode did load and the view is available
|
||||
@property (strong, nonatomic) UIColor *backgroundColor;
|
||||
@end
|
||||
|
||||
@implementation _ASCollectionPendingState
|
||||
@@ -167,25 +162,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
_pendingState.backgroundColor = backgroundColor;
|
||||
} else {
|
||||
ASDisplayNodeAssert([self isNodeLoaded], @"ASTableNode should be loaded if pendingState doesn't exist");
|
||||
self.view.backgroundColor = backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIColor *)backgroundColor
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
return _pendingState.backgroundColor;
|
||||
} else {
|
||||
return self.view.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (ASCollectionView *)view
|
||||
{
|
||||
return (ASCollectionView *)[super view];
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -14,18 +14,13 @@
|
||||
@interface _ASTablePendingState : NSObject
|
||||
@property (weak, nonatomic) id <ASTableDelegate> delegate;
|
||||
@property (weak, nonatomic) id <ASTableDataSource> dataSource;
|
||||
|
||||
// If the background color is applied via the pending state it's applied to the layer of the UITableView.
|
||||
// Unfortunately UITableView does not consider using the layer backgroundColor property as it's background color,
|
||||
// so it needs to be applied to the view after the ASTableNode did load and the view is available
|
||||
@property (strong, nonatomic) UIColor *backgroundColor;
|
||||
@end
|
||||
|
||||
@implementation _ASTablePendingState
|
||||
@end
|
||||
|
||||
@interface ASTableNode ()
|
||||
@property (nonatomic) _ASTablePendingState *pendingState;
|
||||
@property (nonatomic, strong) _ASTablePendingState *pendingState;
|
||||
@end
|
||||
|
||||
@interface ASTableView ()
|
||||
@@ -79,7 +74,6 @@
|
||||
self.pendingState = nil;
|
||||
view.asyncDelegate = pendingState.delegate;
|
||||
view.asyncDataSource = pendingState.dataSource;
|
||||
view.backgroundColor = pendingState.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,25 +133,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
_pendingState.backgroundColor = backgroundColor;
|
||||
} else {
|
||||
ASDisplayNodeAssert([self isNodeLoaded], @"ASTableNode should be loaded if pendingState doesn't exist");
|
||||
self.view.backgroundColor = backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIColor *)backgroundColor
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
return _pendingState.backgroundColor;
|
||||
} else {
|
||||
return self.view.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (ASTableView *)view
|
||||
{
|
||||
return (ASTableView *)[super view];
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user