mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Improve measurement code for cell nodes (#3119)
This commit is contained in:
committed by
GitHub
parent
93809bd4e7
commit
62d7e14ce1
@@ -125,47 +125,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)transitionLayoutWithAnimation:(BOOL)animated
|
- (void)_layoutTransitionMeasurementDidFinish
|
||||||
shouldMeasureAsync:(BOOL)shouldMeasureAsync
|
|
||||||
measurementCompletion:(void(^)())completion
|
|
||||||
{
|
|
||||||
CGSize oldSize = self.calculatedSize;
|
|
||||||
[super transitionLayoutWithAnimation:animated
|
|
||||||
shouldMeasureAsync:shouldMeasureAsync
|
|
||||||
measurementCompletion:^{
|
|
||||||
[self didRelayoutFromOldSize:oldSize toNewSize:self.calculatedSize];
|
|
||||||
if (completion) {
|
|
||||||
completion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
|
|
||||||
animated:(BOOL)animated
|
|
||||||
shouldMeasureAsync:(BOOL)shouldMeasureAsync
|
|
||||||
measurementCompletion:(void(^)())completion
|
|
||||||
{
|
|
||||||
CGSize oldSize = self.calculatedSize;
|
|
||||||
[super transitionLayoutWithSizeRange:constrainedSize
|
|
||||||
animated:animated
|
|
||||||
shouldMeasureAsync:shouldMeasureAsync
|
|
||||||
measurementCompletion:^{
|
|
||||||
[self didRelayoutFromOldSize:oldSize toNewSize:self.calculatedSize];
|
|
||||||
if (completion) {
|
|
||||||
completion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)didRelayoutFromOldSize:(CGSize)oldSize toNewSize:(CGSize)newSize
|
|
||||||
{
|
{
|
||||||
if (_interactionDelegate != nil) {
|
if (_interactionDelegate != nil) {
|
||||||
ASPerformBlockOnMainThread(^{
|
[_interactionDelegate nodeDidInvalidateSize:self];
|
||||||
BOOL sizeChanged = !CGSizeEqualToSize(oldSize, newSize);
|
|
||||||
[_interactionDelegate nodeDidRelayout:self sizeChanged:sizeChanged];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#import <AsyncDisplayKit/ASSectionContext.h>
|
#import <AsyncDisplayKit/ASSectionContext.h>
|
||||||
#import <AsyncDisplayKit/ASCollectionView+Undeprecated.h>
|
#import <AsyncDisplayKit/ASCollectionView+Undeprecated.h>
|
||||||
#import <AsyncDisplayKit/_ASHierarchyChangeSet.h>
|
#import <AsyncDisplayKit/_ASHierarchyChangeSet.h>
|
||||||
|
#import <AsyncDisplayKit/CoreGraphics+ASConvenience.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A macro to get self.collectionNode and assign it to a local variable, or return
|
* A macro to get self.collectionNode and assign it to a local variable, or return
|
||||||
@@ -1563,6 +1564,15 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)dataController:(ASDataController *)dataController presentedSizeForElement:(ASCollectionElement *)element matchesSize:(CGSize)size
|
||||||
|
{
|
||||||
|
NSIndexPath *indexPath = [self indexPathForNode:element.node];
|
||||||
|
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
|
||||||
|
CGRect rect = attributes.frame;
|
||||||
|
return CGSizeEqualToSizeWithIn(rect.size, size, FLT_EPSILON);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
- (id<ASTraitEnvironment>)dataControllerEnvironment
|
- (id<ASTraitEnvironment>)dataControllerEnvironment
|
||||||
{
|
{
|
||||||
return self.collectionNode;
|
return self.collectionNode;
|
||||||
|
|||||||
@@ -1266,6 +1266,12 @@ ASLayoutElementFinalLayoutElementDefault
|
|||||||
return _calculatedDisplayNodeLayout->constrainedSize;
|
return _calculatedDisplayNodeLayout->constrainedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Informs the root node that the intrinsic size of the receiver is no longer valid.
|
||||||
|
*
|
||||||
|
* @discussion The size of a root node is determined by each subnode. Calling invalidateSize will let the root node know
|
||||||
|
* that the intrinsic size of the receiver node is no longer valid and a resizing of the root node needs to happen.
|
||||||
|
*/
|
||||||
- (void)setNeedsLayoutFromAbove
|
- (void)setNeedsLayoutFromAbove
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertThreadAffinity(self);
|
ASDisplayNodeAssertThreadAffinity(self);
|
||||||
@@ -1487,6 +1493,8 @@ ASLayoutElementFinalLayoutElementDefault
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Measurement pass completion
|
// Measurement pass completion
|
||||||
|
// Give the subclass a change to hook into before calling the completion block
|
||||||
|
[self _layoutTransitionMeasurementDidFinish];
|
||||||
if (completion) {
|
if (completion) {
|
||||||
completion();
|
completion();
|
||||||
}
|
}
|
||||||
@@ -1560,6 +1568,11 @@ ASLayoutElementFinalLayoutElementDefault
|
|||||||
return _transitionID;
|
return _transitionID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)_layoutTransitionMeasurementDidFinish
|
||||||
|
{
|
||||||
|
// No-Op in ASDisplayNode
|
||||||
|
}
|
||||||
|
|
||||||
- (void)_finishOrCancelTransition
|
- (void)_finishOrCancelTransition
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
|
|||||||
@@ -1695,6 +1695,22 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)dataController:(ASDataController *)dataController presentedSizeForElement:(ASCollectionElement *)element matchesSize:(CGSize)size
|
||||||
|
{
|
||||||
|
NSIndexPath *indexPath = [self indexPathForNode:element.node];
|
||||||
|
CGRect rect = [self rectForRowAtIndexPath:indexPath];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Weirdly enough, Apple expects the return value in tableView:heightForRowAtIndexPath: to _include_ the height
|
||||||
|
* of the separator, if there is one! So if rectForRow would return 44.0 we need to use 43.5.
|
||||||
|
*/
|
||||||
|
if (self.separatorStyle != UITableViewCellSeparatorStyleNone) {
|
||||||
|
rect.size.height -= 1.0 / ASScreenScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fabs(rect.size.height - size.height) < FLT_EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - ASDataControllerEnvironmentDelegate
|
#pragma mark - ASDataControllerEnvironmentDelegate
|
||||||
|
|
||||||
- (id<ASTraitEnvironment>)dataControllerEnvironment
|
- (id<ASTraitEnvironment>)dataControllerEnvironment
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@class ASCellNode;
|
@class ASCellNode;
|
||||||
@class ASDataController;
|
@class ASDataController;
|
||||||
@class ASElementMap;
|
@class ASElementMap;
|
||||||
|
@class ASCollectionElement;
|
||||||
@class _ASHierarchyChangeSet;
|
@class _ASHierarchyChangeSet;
|
||||||
@protocol ASTraitEnvironment;
|
@protocol ASTraitEnvironment;
|
||||||
@protocol ASSectionContext;
|
@protocol ASSectionContext;
|
||||||
@@ -65,6 +66,11 @@ extern NSString * const ASCollectionInvalidUpdateException;
|
|||||||
*/
|
*/
|
||||||
- (NSUInteger)numberOfSectionsInDataController:(ASDataController *)dataController;
|
- (NSUInteger)numberOfSectionsInDataController:(ASDataController *)dataController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns if the collection element size matches a given size
|
||||||
|
*/
|
||||||
|
- (BOOL)dataController:(ASDataController *)dataController presentedSizeForElement:(ASCollectionElement *)element matchesSize:(CGSize)size;
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|
||||||
- (NSArray<NSString *> *)dataController:(ASDataController *)dataController supplementaryNodeKindsInSections:(NSIndexSet *)sections;
|
- (NSArray<NSString *> *)dataController:(ASDataController *)dataController supplementaryNodeKindsInSections:(NSIndexSet *)sections;
|
||||||
|
|||||||
@@ -640,10 +640,9 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
|||||||
NSString *kind = node.collectionElement.supplementaryElementKind ?: ASDataControllerRowNodeKind;
|
NSString *kind = node.collectionElement.supplementaryElementKind ?: ASDataControllerRowNodeKind;
|
||||||
NSIndexPath *indexPath = [_pendingMap indexPathForElement:node.collectionElement];
|
NSIndexPath *indexPath = [_pendingMap indexPathForElement:node.collectionElement];
|
||||||
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath];
|
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath];
|
||||||
|
|
||||||
CGSize oldSize = node.bounds.size;
|
|
||||||
[self _layoutNode:node withConstrainedSize:constrainedSize];
|
[self _layoutNode:node withConstrainedSize:constrainedSize];
|
||||||
if (! CGSizeEqualToSize(node.frame.size, oldSize)) {
|
BOOL matchesSize = [_dataSource dataController:self presentedSizeForElement:node.collectionElement matchesSize:node.frame.size];
|
||||||
|
if (! matchesSize) {
|
||||||
[nodesSizesChanged addObject:node];
|
[nodesSizesChanged addObject:node];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,20 +214,18 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyState(ASHierarchyStat
|
|||||||
*/
|
*/
|
||||||
- (BOOL)shouldScheduleDisplayWithNewInterfaceState:(ASInterfaceState)newInterfaceState;
|
- (BOOL)shouldScheduleDisplayWithNewInterfaceState:(ASInterfaceState)newInterfaceState;
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract Informs the root node that the intrinsic size of the receiver is no longer valid.
|
|
||||||
*
|
|
||||||
* @discussion The size of a root node is determined by each subnode. Calling invalidateSize will let the root node know
|
|
||||||
* that the intrinsic size of the receiver node is no longer valid and a resizing of the root node needs to happen.
|
|
||||||
*/
|
|
||||||
- (void)setNeedsLayoutFromAbove;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Subclass hook for nodes that are acting as root nodes. This method is called if one of the subnodes
|
* @abstract Subclass hook for nodes that are acting as root nodes. This method is called if one of the subnodes
|
||||||
* size is invalidated and may need to result in a different size as the current calculated size.
|
* size is invalidated and may need to result in a different size as the current calculated size.
|
||||||
*/
|
*/
|
||||||
- (void)_locked_rootNodeDidInvalidateSize;
|
- (void)_locked_rootNodeDidInvalidateSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Subclass hook for nodes that are acting as root nodes. This method is called after measurement
|
||||||
|
* finished in a layout transition but before the measurement completion handler is called
|
||||||
|
*/
|
||||||
|
- (void)_layoutTransitionMeasurementDidFinish;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface UIView (ASDisplayNodeInternal)
|
@interface UIView (ASDisplayNodeInternal)
|
||||||
|
|||||||
Reference in New Issue
Block a user