Expose the layout's immediate sublayouts as the accessing nodes

This commit is contained in:
Levi McCallum 2016-02-09 14:12:05 -08:00
parent 4361c3bbb4
commit 1513ee8ca5
4 changed files with 68 additions and 60 deletions

View File

@ -15,10 +15,21 @@
*/ */
- (BOOL)isAnimated; - (BOOL)isAnimated;
/**
* @abstract The destination layout being transitioned to
*/
- (ASLayout *)layout; - (ASLayout *)layout;
/**
* @abstrat The destination constrainedSize being transitioned to
*/
- (ASSizeRange)constrainedSize; - (ASSizeRange)constrainedSize;
/**
* @abstract Subnodes in the new layout
*/
- (NSArray<ASDisplayNode *> *)subnodes;
/** /**
@abstract The frame for the given node before the transition began. @abstract The frame for the given node before the transition began.
@discussion Returns CGRectNull if the node was not in the hierarchy before the transition. @discussion Returns CGRectNull if the node was not in the hierarchy before the transition.

View File

@ -652,11 +652,10 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
{ {
ASDisplayNodeAssertThreadAffinity(self); ASDisplayNodeAssertThreadAffinity(self);
ASDN::MutexLocker l(_propertyLock); ASDN::MutexLocker l(_propertyLock);
ASLayout *newLayout;
if (![self __shouldSize]) if (![self __shouldSize])
return nil; return newLayout;
ASLayout *newLayout;
// only calculate the size if // only calculate the size if
// - we haven't already // - we haven't already
@ -664,32 +663,29 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
if (!_flags.isMeasured || !ASSizeRangeEqualToSizeRange(constrainedSize, _constrainedSize)) { if (!_flags.isMeasured || !ASSizeRangeEqualToSizeRange(constrainedSize, _constrainedSize)) {
newLayout = [self calculateLayoutThatFits:constrainedSize]; newLayout = [self calculateLayoutThatFits:constrainedSize];
if ([[self class] usesImplicitHierarchyManagement]) { if (_layout) {
if (_layout) { NSIndexSet *insertions, *deletions;
NSIndexSet *insertions, *deletions; [_layout.immediateSublayouts asdk_diffWithArray:newLayout.immediateSublayouts
[_layout.immediateSublayouts asdk_diffWithArray:newLayout.immediateSublayouts insertions:&insertions
insertions:&insertions deletions:&deletions
deletions:&deletions compareBlock:^BOOL(ASLayout *lhs, ASLayout *rhs) {
compareBlock:^BOOL(ASLayout *lhs, ASLayout *rhs) { return ASObjectIsEqual(lhs.layoutableObject, rhs.layoutableObject);
return ASObjectIsEqual(lhs.layoutableObject, rhs.layoutableObject); }];
}]; _insertedSubnodes = [self _nodesInLayout:newLayout atIndexes:insertions];
_insertedSubnodes = [self _nodesInLayout:newLayout atIndexes:insertions]; _deletedSubnodes = [self _nodesInLayout:_layout atIndexes:deletions filterNodes:_insertedSubnodes];
_deletedSubnodes = [self _nodesInLayout:_layout atIndexes:deletions filterNodes:_insertedSubnodes]; } else {
} else { NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [newLayout.immediateSublayouts count])];
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [newLayout.immediateSublayouts count])]; _insertedSubnodes = [self _nodesInLayout:newLayout atIndexes:indexes];
_insertedSubnodes = [self _nodesInLayout:newLayout atIndexes:indexes]; _deletedSubnodes = nil;
_deletedSubnodes = nil; }
}
if (animated) {
if (animated) { [self __transitionToLayout:newLayout constrainedSize:constrainedSize animated:animated];
[self __transitionToLayout:newLayout constrainedSize:constrainedSize animated:animated]; } else {
} else { if ([[self class] usesImplicitHierarchyManagement]) {
[self __implicitlyInsertSubnodes]; [self __implicitlyInsertSubnodes];
[self __implicitlyRemoveSubnodes]; [self __implicitlyRemoveSubnodes];
[self __updateLayout:newLayout constrainedSize:constrainedSize];
} }
} else {
// 1.9.x code path
[self __updateLayout:newLayout constrainedSize:constrainedSize]; [self __updateLayout:newLayout constrainedSize:constrainedSize];
} }
} }
@ -1079,52 +1075,33 @@ static inline CATransform3D _calculateTransformFromReferenceToTarget(ASDisplayNo
- (void)__implicitlyInsertSubnodes - (void)__implicitlyInsertSubnodes
{ {
if ([_insertedSubnodes count]) { for (_ASDisplayNodePosition *position in _insertedSubnodes) {
for (_ASDisplayNodePosition *position in _insertedSubnodes) { [self insertSubnode:position.node atIndex:position.index];
[self insertSubnode:position.node atIndex:position.index];
}
_insertedSubnodes = nil;
} }
_insertedSubnodes = nil;
} }
- (void)__implicitlyRemoveSubnodes - (void)__implicitlyRemoveSubnodes
{ {
if ([_deletedSubnodes count]) { for (_ASDisplayNodePosition *position in _deletedSubnodes) {
for (_ASDisplayNodePosition *position in _deletedSubnodes) { [position.node removeFromSupernode];
[position.node removeFromSupernode];
}
_deletedSubnodes = nil;
} }
_deletedSubnodes = nil;
} }
#pragma mark - _ASTransitionContextDelegate #pragma mark - _ASTransitionContextDelegate
- (NSArray<ASDisplayNode *> *)currentSubnodesWithTransitionContext:(_ASTransitionContext *)context
{
return _subnodes;
}
- (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete - (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete
{ {
[self didCompleteTransitionLayout:context]; [self didCompleteTransitionLayout:context];
_transitionContext = nil; _transitionContext = nil;
} }
- (CGRect)transitionContext:(_ASTransitionContext *)context initialFrameForNode:(ASDisplayNode *)node
{
for (ASDisplayNode *subnode in _subnodes) {
if (ASObjectIsEqual(node, subnode)) {
return node.frame;
}
}
return CGRectNull;
}
- (CGRect)transitionContext:(_ASTransitionContext *)context finalFrameForNode:(ASDisplayNode *)node
{
for (ASLayout *layout in _layout.sublayouts) {
if (ASObjectIsEqual(node, layout.layoutableObject)) {
return [self _adjustedFrameForLayout:layout];
}
}
return CGRectNull;
}
#pragma mark - _ASDisplayLayerDelegate #pragma mark - _ASDisplayLayerDelegate
- (void)willDisplayAsyncLayer:(_ASDisplayLayer *)layer - (void)willDisplayAsyncLayer:(_ASDisplayLayer *)layer

View File

@ -15,9 +15,8 @@
@protocol _ASTransitionContextDelegate <NSObject> @protocol _ASTransitionContextDelegate <NSObject>
- (NSArray<ASDisplayNode *> *)currentSubnodesWithTransitionContext:(_ASTransitionContext *)context;
- (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete; - (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete;
- (CGRect)transitionContext:(_ASTransitionContext *)context initialFrameForNode:(ASDisplayNode *)node;
- (CGRect)transitionContext:(_ASTransitionContext *)context finalFrameForNode:(ASDisplayNode *)node;
@end @end

View File

@ -8,6 +8,8 @@
#import "_ASTransitionContext.h" #import "_ASTransitionContext.h"
#import "ASLayout.h"
@interface _ASTransitionContext () @interface _ASTransitionContext ()
@property (weak, nonatomic) id<_ASTransitionContextDelegate> delegate; @property (weak, nonatomic) id<_ASTransitionContextDelegate> delegate;
@ -30,12 +32,31 @@
- (CGRect)initialFrameForNode:(ASDisplayNode *)node - (CGRect)initialFrameForNode:(ASDisplayNode *)node
{ {
return [_delegate transitionContext:self initialFrameForNode:node]; for (ASDisplayNode *subnode in [_delegate currentSubnodesWithTransitionContext:self]) {
if (node == subnode) {
return node.frame;
}
}
return CGRectZero;
} }
- (CGRect)finalFrameForNode:(ASDisplayNode *)node - (CGRect)finalFrameForNode:(ASDisplayNode *)node
{ {
return [_delegate transitionContext:self finalFrameForNode:node]; for (ASLayout *layout in _layout.immediateSublayouts) {
if (layout.layoutableObject == node) {
return [layout frame];
}
}
return CGRectZero;
}
- (NSArray<ASDisplayNode *> *)subnodes
{
NSMutableArray<ASDisplayNode *> *subnodes = [NSMutableArray array];
for (ASLayout *sublayout in _layout.immediateSublayouts) {
[subnodes addObject:(ASDisplayNode *)sublayout.layoutableObject];
}
return subnodes;
} }
- (void)completeTransition:(BOOL)didComplete - (void)completeTransition:(BOOL)didComplete