mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +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
|
@interface _ASCollectionPendingState : NSObject
|
||||||
@property (weak, nonatomic) id <ASCollectionDelegate> delegate;
|
@property (weak, nonatomic) id <ASCollectionDelegate> delegate;
|
||||||
@property (weak, nonatomic) id <ASCollectionDataSource> dataSource;
|
@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
|
@end
|
||||||
|
|
||||||
@implementation _ASCollectionPendingState
|
@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
|
- (ASCollectionView *)view
|
||||||
{
|
{
|
||||||
return (ASCollectionView *)[super view];
|
return (ASCollectionView *)[super view];
|
||||||
|
|||||||
@@ -83,6 +83,13 @@ BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector)
|
|||||||
return ASSubclassOverridesSelector([ASDisplayNode class], subclass, 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)
|
_ASPendingState *ASDisplayNodeGetPendingState(ASDisplayNode *node)
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(node->_propertyLock);
|
ASDN::MutexLocker l(node->_propertyLock);
|
||||||
@@ -954,8 +961,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
if (self.layerBacked) {
|
if (self.layerBacked) {
|
||||||
[_pendingViewState applyToLayer:self.layer];
|
[_pendingViewState applyToLayer:self.layer];
|
||||||
} else {
|
} else {
|
||||||
BOOL setFrameDirectly = (_flags.synchronous && !_flags.layerBacked);
|
BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(_flags);
|
||||||
[_pendingViewState applyToView:self.view setFrameDirectly:setFrameDirectly];
|
[_pendingViewState applyToView:self.view withSpecialPropertiesHandling:specialPropertiesHandling];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_pendingViewState clearChanges];
|
[_pendingViewState clearChanges];
|
||||||
|
|||||||
@@ -14,18 +14,13 @@
|
|||||||
@interface _ASTablePendingState : NSObject
|
@interface _ASTablePendingState : NSObject
|
||||||
@property (weak, nonatomic) id <ASTableDelegate> delegate;
|
@property (weak, nonatomic) id <ASTableDelegate> delegate;
|
||||||
@property (weak, nonatomic) id <ASTableDataSource> dataSource;
|
@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
|
@end
|
||||||
|
|
||||||
@implementation _ASTablePendingState
|
@implementation _ASTablePendingState
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ASTableNode ()
|
@interface ASTableNode ()
|
||||||
@property (nonatomic) _ASTablePendingState *pendingState;
|
@property (nonatomic, strong) _ASTablePendingState *pendingState;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ASTableView ()
|
@interface ASTableView ()
|
||||||
@@ -79,7 +74,6 @@
|
|||||||
self.pendingState = nil;
|
self.pendingState = nil;
|
||||||
view.asyncDelegate = pendingState.delegate;
|
view.asyncDelegate = pendingState.delegate;
|
||||||
view.asyncDataSource = pendingState.dataSource;
|
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
|
- (ASTableView *)view
|
||||||
{
|
{
|
||||||
return (ASTableView *)[super view];
|
return (ASTableView *)[super view];
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#import "ASPendingStateController.h"
|
#import "ASPendingStateController.h"
|
||||||
#import "ASThread.h"
|
#import "ASThread.h"
|
||||||
#import "ASTextNode.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.
|
* 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:
|
// For classes like ASTableNode, ASCollectionNode, ASScrollNode and similar - make sure UIView gets setFrame:
|
||||||
struct ASDisplayNodeFlags flags = _flags;
|
struct ASDisplayNodeFlags flags = _flags;
|
||||||
BOOL setFrameDirectly = flags.synchronous && !flags.layerBacked;
|
BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(flags);
|
||||||
|
|
||||||
BOOL nodeLoaded = __loaded(self);
|
BOOL nodeLoaded = __loaded(self);
|
||||||
BOOL isMainThread = ASDisplayNodeThreadIsMain();
|
BOOL isMainThread = ASDisplayNodeThreadIsMain();
|
||||||
if (!setFrameDirectly) {
|
if (!specialPropertiesHandling) {
|
||||||
BOOL canReadProperties = isMainThread || !nodeLoaded;
|
BOOL canReadProperties = isMainThread || !nodeLoaded;
|
||||||
if (canReadProperties) {
|
if (canReadProperties) {
|
||||||
// We don't have to set frame directly, and we can read current properties.
|
// 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) {
|
if (shouldApply) {
|
||||||
CGColorRef oldBackgroundCGColor = _layer.backgroundColor;
|
CGColorRef oldBackgroundCGColor = _layer.backgroundColor;
|
||||||
_layer.backgroundColor = newBackgroundCGColor;
|
_layer.backgroundColor = newBackgroundCGColor;
|
||||||
|
|
||||||
|
BOOL specialPropertiesHandling = ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(_flags);
|
||||||
|
if (specialPropertiesHandling) {
|
||||||
|
_view.backgroundColor = newBackgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CGColorEqualToColor(oldBackgroundCGColor, newBackgroundCGColor)) {
|
if (!CGColorEqualToColor(oldBackgroundCGColor, newBackgroundCGColor)) {
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,10 @@
|
|||||||
@class _ASDisplayLayer;
|
@class _ASDisplayLayer;
|
||||||
@class _ASPendingState;
|
@class _ASPendingState;
|
||||||
@class ASSentinel;
|
@class ASSentinel;
|
||||||
|
struct ASDisplayNodeFlags;
|
||||||
|
|
||||||
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
|
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
|
||||||
|
BOOL ASDisplayNodeNeedsSpecialPropertiesSettingHandlingForFlags(ASDisplayNodeFlags flags);
|
||||||
|
|
||||||
/// Get the pending view state for the node, creating one if needed.
|
/// Get the pending view state for the node, creating one if needed.
|
||||||
_ASPendingState *ASDisplayNodeGetPendingState(ASDisplayNode *node);
|
_ASPendingState *ASDisplayNodeGetPendingState(ASDisplayNode *node);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
// Supports all of the properties included in the ASDisplayNodeViewProperties protocol
|
// 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;
|
- (void)applyToLayer:(CALayer *)layer;
|
||||||
|
|
||||||
+ (_ASPendingState *)pendingViewStateFromLayer:(CALayer *)layer;
|
+ (_ASPendingState *)pendingViewStateFromLayer:(CALayer *)layer;
|
||||||
|
|||||||
@@ -745,7 +745,7 @@ static UIColor *defaultTintColor = nil;
|
|||||||
ASPendingStateApplyMetricsToLayer(self, layer);
|
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
|
Use our convenience setters blah here instead of layer.blah
|
||||||
@@ -789,9 +789,16 @@ static UIColor *defaultTintColor = nil;
|
|||||||
if (flags.setClipsToBounds)
|
if (flags.setClipsToBounds)
|
||||||
view.clipsToBounds = clipsToBounds;
|
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;
|
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)
|
if (flags.setTintColor)
|
||||||
view.tintColor = self.tintColor;
|
view.tintColor = self.tintColor;
|
||||||
|
|
||||||
@@ -907,8 +914,7 @@ static UIColor *defaultTintColor = nil;
|
|||||||
if (flags.setAccessibilityPath)
|
if (flags.setAccessibilityPath)
|
||||||
view.accessibilityPath = accessibilityPath;
|
view.accessibilityPath = accessibilityPath;
|
||||||
|
|
||||||
// For classes like ASTableNode, ASCollectionNode, ASScrollNode and similar - make sure UIView gets setFrame:
|
if (flags.setFrame && specialPropertiesHandling) {
|
||||||
if (flags.setFrame && setFrameDirectly) {
|
|
||||||
// Frame is only defined when transform is identity because we explicitly diverge from CALayer behavior and define frame without transform
|
// Frame is only defined when transform is identity because we explicitly diverge from CALayer behavior and define frame without transform
|
||||||
#if DEBUG
|
#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.
|
// 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