mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-15 00:19:03 +00:00
Allow layouts to be accessible in context
This commit is contained in:
parent
6aae68ead4
commit
6f37bb40d9
@ -8,6 +8,9 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASDisplayNode.h>
|
||||
|
||||
extern NSString * const ASTransitionContextFromLayoutKey;
|
||||
extern NSString * const ASTransitionContextToLayoutKey;
|
||||
|
||||
@protocol ASContextTransitioning <NSObject>
|
||||
|
||||
/**
|
||||
@ -16,19 +19,19 @@
|
||||
- (BOOL)isAnimated;
|
||||
|
||||
/**
|
||||
* @abstract The destination layout being transitioned to
|
||||
* @abstract Retrieve either the "from" or "to" layout
|
||||
*/
|
||||
- (ASLayout *)layout;
|
||||
- (ASLayout *)layoutForKey:(NSString *)key;
|
||||
|
||||
/**
|
||||
* @abstrat The destination constrainedSize being transitioned to
|
||||
* @abstract Retrieve either the "from" or "to" constrainedSize
|
||||
*/
|
||||
- (ASSizeRange)constrainedSize;
|
||||
- (ASSizeRange)constrainedSizeForKey:(NSString *)key;
|
||||
|
||||
/**
|
||||
* @abstract Subnodes in the new layout
|
||||
* @abstract Retrieve the subnodes from either the "from" or "to" layout
|
||||
*/
|
||||
- (NSArray<ASDisplayNode *> *)subnodes;
|
||||
- (NSArray<ASDisplayNode *> *)subnodesForKey:(NSString *)key;
|
||||
|
||||
/**
|
||||
* @abstract Subnodes that have been inserted in the layout transition
|
||||
|
@ -610,34 +610,43 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
|
||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
||||
{
|
||||
return [self measureWithSizeRange:constrainedSize completion:^(ASLayout *pendingLayout, ASSizeRange constrainedSize) {
|
||||
return [self measureWithSizeRange:constrainedSize completion:^{
|
||||
if ([[self class] usesImplicitHierarchyManagement]) {
|
||||
[self __implicitlyInsertSubnodes];
|
||||
[self __implicitlyRemoveSubnodes];
|
||||
}
|
||||
[self __applyLayout:pendingLayout constrainedSize:constrainedSize];
|
||||
[self __completeLayoutCalculation];
|
||||
}];
|
||||
}
|
||||
|
||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize completion:(void(^)(ASLayout *, ASSizeRange))completion
|
||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize completion:(void(^)())completion
|
||||
{
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
if (![self __shouldSize])
|
||||
return nil;
|
||||
|
||||
ASLayout *pendingLayout = _layout;
|
||||
|
||||
// only calculate the size if
|
||||
// - we haven't already
|
||||
// - the constrained size range is different
|
||||
if (!_flags.isMeasured || !ASSizeRangeEqualToSizeRange(constrainedSize, _constrainedSize)) {
|
||||
pendingLayout = [self calculateLayoutThatFits:constrainedSize];
|
||||
[self __calculateSubnodeOperationsWithPendingLayout:pendingLayout currentLayout:_layout];
|
||||
completion(pendingLayout, constrainedSize);
|
||||
_previousLayout = _layout;
|
||||
_layout = [self calculateLayoutThatFits:constrainedSize];
|
||||
|
||||
ASDisplayNodeAssertTrue(_layout.layoutableObject == self);
|
||||
ASDisplayNodeAssertTrue(_layout.size.width >= 0.0);
|
||||
ASDisplayNodeAssertTrue(_layout.size.height >= 0.0);
|
||||
|
||||
_previousConstrainedSize = _constrainedSize;
|
||||
_constrainedSize = constrainedSize;
|
||||
|
||||
[self __calculateSubnodeOperationsWithLayout:_layout previousLayout:_previousLayout];
|
||||
_flags.isMeasured = YES;
|
||||
|
||||
completion();
|
||||
}
|
||||
|
||||
return pendingLayout;
|
||||
return _layout;
|
||||
}
|
||||
|
||||
- (ASLayout *)transitionLayoutWithAnimation:(BOOL)animated
|
||||
@ -648,50 +657,41 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
|
||||
- (ASLayout *)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize animated:(BOOL)animated
|
||||
{
|
||||
return [self measureWithSizeRange:constrainedSize completion:^(ASLayout *pendingLayout, ASSizeRange constrainedSize) {
|
||||
_transitionContext = [[_ASTransitionContext alloc] initWithLayout:pendingLayout
|
||||
constrainedSize:constrainedSize
|
||||
animated:animated
|
||||
delegate:self];
|
||||
return [self measureWithSizeRange:constrainedSize completion:^{
|
||||
_transitionContext = [[_ASTransitionContext alloc] initWithAnimation:animated delegate:self];
|
||||
[self __implicitlyInsertSubnodes];
|
||||
[self animateLayoutTransition:_transitionContext];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)__calculateSubnodeOperationsWithPendingLayout:(ASLayout *)pendingLayout currentLayout:(ASLayout *)currentLayout
|
||||
- (void)__calculateSubnodeOperationsWithLayout:(ASLayout *)layout previousLayout:(ASLayout *)previousLayout
|
||||
{
|
||||
if (_layout) {
|
||||
if (previousLayout) {
|
||||
NSIndexSet *insertions, *deletions;
|
||||
[currentLayout.immediateSublayouts asdk_diffWithArray:pendingLayout.immediateSublayouts
|
||||
[previousLayout.immediateSublayouts asdk_diffWithArray:layout.immediateSublayouts
|
||||
insertions:&insertions
|
||||
deletions:&deletions
|
||||
compareBlock:^BOOL(ASLayout *lhs, ASLayout *rhs) {
|
||||
return ASObjectIsEqual(lhs.layoutableObject, rhs.layoutableObject);
|
||||
}];
|
||||
filterNodesInLayoutAtIndexes(pendingLayout, insertions, &_insertedSubnodes, &_insertedSubnodePositions);
|
||||
filterNodesInLayoutAtIndexesWithIntersectingNodes(currentLayout,
|
||||
filterNodesInLayoutAtIndexes(layout, insertions, &_insertedSubnodes, &_insertedSubnodePositions);
|
||||
filterNodesInLayoutAtIndexesWithIntersectingNodes(previousLayout,
|
||||
deletions,
|
||||
_insertedSubnodes,
|
||||
&_removedSubnodes,
|
||||
&_removedSubnodePositions);
|
||||
} else {
|
||||
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [pendingLayout.immediateSublayouts count])];
|
||||
filterNodesInLayoutAtIndexes(pendingLayout, indexes, &_insertedSubnodes, &_insertedSubnodePositions);
|
||||
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [layout.immediateSublayouts count])];
|
||||
filterNodesInLayoutAtIndexes(layout, indexes, &_insertedSubnodes, &_insertedSubnodePositions);
|
||||
_removedSubnodes = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)__applyLayout:(ASLayout *)layout constrainedSize:(ASSizeRange)constrainedSize
|
||||
- (void)__completeLayoutCalculation
|
||||
{
|
||||
ASDisplayNodeAssertTrue(layout.layoutableObject == self);
|
||||
ASDisplayNodeAssertTrue(layout.size.width >= 0.0);
|
||||
ASDisplayNodeAssertTrue(layout.size.height >= 0.0);
|
||||
|
||||
_layout = layout;
|
||||
_constrainedSize = constrainedSize;
|
||||
_flags.isMeasured = YES;
|
||||
_insertedSubnodes = nil;
|
||||
_removedSubnodes = nil;
|
||||
_previousLayout = nil;
|
||||
[self calculatedLayoutDidChange];
|
||||
|
||||
// we generate placeholders at measureWithSizeRange: time so that a node is guaranteed
|
||||
@ -777,7 +777,7 @@ static inline void filterNodesInLayoutAtIndexesWithIntersectingNodes(
|
||||
- (void)didCompleteTransitionLayout:(id<ASContextTransitioning>)context
|
||||
{
|
||||
[self __implicitlyRemoveSubnodes];
|
||||
[self __applyLayout:context.layout constrainedSize:context.constrainedSize];
|
||||
[self __completeLayoutCalculation];
|
||||
}
|
||||
|
||||
#pragma mark - Implicit node hierarchy managagment
|
||||
@ -814,6 +814,27 @@ static inline void filterNodesInLayoutAtIndexesWithIntersectingNodes(
|
||||
return _removedSubnodes;
|
||||
}
|
||||
|
||||
- (ASLayout *)transitionContext:(_ASTransitionContext *)context layoutForKey:(NSString *)key
|
||||
{
|
||||
if ([key isEqualToString:ASTransitionContextFromLayoutKey]) {
|
||||
return _previousLayout;
|
||||
} else if ([key isEqualToString:ASTransitionContextToLayoutKey]) {
|
||||
return _layout;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
- (ASSizeRange)transitionContext:(_ASTransitionContext *)context constrainedSizeForKey:(NSString *)key
|
||||
{
|
||||
if ([key isEqualToString:ASTransitionContextFromLayoutKey]) {
|
||||
return _previousConstrainedSize;
|
||||
} else if ([key isEqualToString:ASTransitionContextToLayoutKey]) {
|
||||
return _constrainedSize;
|
||||
} else {
|
||||
return ASSizeRangeMake(CGSizeZero, CGSizeZero);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete
|
||||
{
|
||||
[self didCompleteTransitionLayout:context];
|
||||
|
@ -62,8 +62,12 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
|
||||
// This is the desired contentsScale, not the scale at which the layer's contents should be displayed
|
||||
CGFloat _contentsScaleForDisplay;
|
||||
|
||||
ASLayout *_previousLayout;
|
||||
ASLayout *_layout;
|
||||
|
||||
ASSizeRange _previousConstrainedSize;
|
||||
ASSizeRange _constrainedSize;
|
||||
|
||||
UIEdgeInsets _hitTestSlop;
|
||||
NSMutableArray *_subnodes;
|
||||
|
||||
|
@ -16,9 +16,13 @@
|
||||
@protocol _ASTransitionContextDelegate <NSObject>
|
||||
|
||||
- (NSArray<ASDisplayNode *> *)currentSubnodesWithTransitionContext:(_ASTransitionContext *)context;
|
||||
|
||||
- (NSArray<ASDisplayNode *> *)insertedSubnodesWithTransitionContext:(_ASTransitionContext *)context;
|
||||
- (NSArray<ASDisplayNode *> *)removedSubnodesWithTransitionContext:(_ASTransitionContext *)context;
|
||||
|
||||
- (ASLayout *)transitionContext:(_ASTransitionContext *)context layoutForKey:(NSString *)key;
|
||||
- (ASSizeRange)transitionContext:(_ASTransitionContext *)context constrainedSizeForKey:(NSString *)key;
|
||||
|
||||
- (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete;
|
||||
|
||||
@end
|
||||
@ -27,10 +31,6 @@
|
||||
|
||||
@property (assign, readonly, nonatomic, getter=isAnimated) BOOL animated;
|
||||
|
||||
@property (strong, readonly) ASLayout *layout;
|
||||
|
||||
@property (assign, readonly) ASSizeRange constrainedSize;
|
||||
|
||||
- (instancetype)initWithLayout:(ASLayout *)layout constrainedSize:(ASSizeRange)constrainedSize animated:(BOOL)animated delegate:(id<_ASTransitionContextDelegate>)delegate;
|
||||
- (instancetype)initWithAnimation:(BOOL)animated delegate:(id<_ASTransitionContextDelegate>)delegate;
|
||||
|
||||
@end
|
||||
|
@ -10,6 +10,10 @@
|
||||
|
||||
#import "ASLayout.h"
|
||||
|
||||
|
||||
NSString * const ASTransitionContextFromLayoutKey = @"org.asyncdisplaykit.ASTransitionContextFromLayoutKey";
|
||||
NSString * const ASTransitionContextToLayoutKey = @"org.asyncdisplaykit.ASTransitionContextToLayoutKey";
|
||||
|
||||
@interface _ASTransitionContext ()
|
||||
|
||||
@property (weak, nonatomic) id<_ASTransitionContextDelegate> delegate;
|
||||
@ -18,12 +22,10 @@
|
||||
|
||||
@implementation _ASTransitionContext
|
||||
|
||||
- (instancetype)initWithLayout:(ASLayout *)layout constrainedSize:(ASSizeRange)constrainedSize animated:(BOOL)animated delegate:(id<_ASTransitionContextDelegate>)delegate
|
||||
- (instancetype)initWithAnimation:(BOOL)animated delegate:(id<_ASTransitionContextDelegate>)delegate
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_layout = layout;
|
||||
_constrainedSize = constrainedSize;
|
||||
_animated = animated;
|
||||
_delegate = delegate;
|
||||
}
|
||||
@ -32,6 +34,16 @@
|
||||
|
||||
#pragma mark - ASContextTransitioning Protocol Implementation
|
||||
|
||||
- (ASLayout *)layoutForKey:(NSString *)key
|
||||
{
|
||||
return [_delegate transitionContext:self layoutForKey:key];
|
||||
}
|
||||
|
||||
- (ASSizeRange)constrainedSizeForKey:(NSString *)key
|
||||
{
|
||||
return [_delegate transitionContext:self constrainedSizeForKey:key];
|
||||
}
|
||||
|
||||
- (CGRect)initialFrameForNode:(ASDisplayNode *)node
|
||||
{
|
||||
for (ASDisplayNode *subnode in [_delegate currentSubnodesWithTransitionContext:self]) {
|
||||
@ -44,7 +56,7 @@
|
||||
|
||||
- (CGRect)finalFrameForNode:(ASDisplayNode *)node
|
||||
{
|
||||
for (ASLayout *layout in _layout.sublayouts) {
|
||||
for (ASLayout *layout in [self layoutForKey:ASTransitionContextToLayoutKey].sublayouts) {
|
||||
if (layout.layoutableObject == node) {
|
||||
return [layout frame];
|
||||
}
|
||||
@ -52,10 +64,10 @@
|
||||
return CGRectZero;
|
||||
}
|
||||
|
||||
- (NSArray<ASDisplayNode *> *)subnodes
|
||||
- (NSArray<ASDisplayNode *> *)subnodesForKey:(NSString *)key
|
||||
{
|
||||
NSMutableArray<ASDisplayNode *> *subnodes = [NSMutableArray array];
|
||||
for (ASLayout *sublayout in _layout.immediateSublayouts) {
|
||||
for (ASLayout *sublayout in [self layoutForKey:key].immediateSublayouts) {
|
||||
[subnodes addObject:(ASDisplayNode *)sublayout.layoutableObject];
|
||||
}
|
||||
return subnodes;
|
||||
|
Loading…
x
Reference in New Issue
Block a user