[Layout Transition] Reset the alpha value for inserted and removed subnode to initial value (#2729)

* Reset the alpha value for removed subnodes in layout transition to 1 after removal

* Some improvements

* Restore alpha value of inserted and removed subnodes to original alpha value in animated layout transition
This commit is contained in:
Michael Schneider 2016-12-12 19:46:01 -08:00 committed by appleguy
parent 03045ee549
commit ddc23af8e7
3 changed files with 48 additions and 8 deletions

View File

@ -1057,9 +1057,6 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
// Kick off animating the layout transition // Kick off animating the layout transition
[self animateLayoutTransition:_pendingLayoutTransitionContext]; [self animateLayoutTransition:_pendingLayoutTransitionContext];
// Mark transaction as finished
[self _finishOrCancelTransition];
}); });
}; };
@ -1184,6 +1181,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
NSMutableArray<ASDisplayNode *> *insertedSubnodes = [[context insertedSubnodes] mutableCopy]; NSMutableArray<ASDisplayNode *> *insertedSubnodes = [[context insertedSubnodes] mutableCopy];
NSMutableArray<ASDisplayNode *> *movedSubnodes = [NSMutableArray array]; NSMutableArray<ASDisplayNode *> *movedSubnodes = [NSMutableArray array];
NSMutableArray<_ASAnimatedTransitionContext *> *insertedSubnodeContexts = [NSMutableArray array];
NSMutableArray<_ASAnimatedTransitionContext *> *removedSubnodeContexts = [NSMutableArray array];
for (ASDisplayNode *subnode in [context subnodesForKey:ASTransitionContextToLayoutKey]) { for (ASDisplayNode *subnode in [context subnodesForKey:ASTransitionContextToLayoutKey]) {
if ([insertedSubnodes containsObject:subnode] == NO) { if ([insertedSubnodes containsObject:subnode] == NO) {
// This is an existing subnode, check if it is resized, moved or both // This is an existing subnode, check if it is resized, moved or both
@ -1207,6 +1207,15 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
} }
} }
// Create contexts for inserted and removed subnodes
for (ASDisplayNode *insertedSubnode in insertedSubnodes) {
[insertedSubnodeContexts addObject:[_ASAnimatedTransitionContext contextForNode:insertedSubnode alpha:insertedSubnode.alpha]];
}
for (ASDisplayNode *removedSubnode in removedSubnodes) {
[removedSubnodeContexts addObject:[_ASAnimatedTransitionContext contextForNode:removedSubnode alpha:removedSubnode.alpha]];
}
// Fade out inserted subnodes
for (ASDisplayNode *insertedSubnode in insertedSubnodes) { for (ASDisplayNode *insertedSubnode in insertedSubnodes) {
insertedSubnode.frame = [context finalFrameForNode:insertedSubnode]; insertedSubnode.frame = [context finalFrameForNode:insertedSubnode];
insertedSubnode.alpha = 0; insertedSubnode.alpha = 0;
@ -1222,8 +1231,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
} }
// Fade inserted subnodes in // Fade inserted subnodes in
for (ASDisplayNode *insertedSubnode in insertedSubnodes) { for (_ASAnimatedTransitionContext *insertedSubnodeContext in insertedSubnodeContexts) {
insertedSubnode.alpha = 1; insertedSubnodeContext.node.alpha = insertedSubnodeContext.alpha;
} }
// Update frame of self and moved subnodes // Update frame of self and moved subnodes
@ -1238,6 +1247,10 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
movedSubnode.frame = [context finalFrameForNode:movedSubnode]; movedSubnode.frame = [context finalFrameForNode:movedSubnode];
} }
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
// Restore all removed subnode alpha values
for (_ASAnimatedTransitionContext *removedSubnodeContext in removedSubnodeContexts) {
removedSubnodeContext.node.alpha = removedSubnodeContext.alpha;
}
for (UIView *removedView in removedViews) { for (UIView *removedView in removedViews) {
[removedView removeFromSuperview]; [removedView removeFromSuperview];
} }
@ -1246,7 +1259,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
}]; }];
} }
/* /**
* Hook for subclasses to clean up nodes after the transition happened. Furthermore this can be used from subclasses * Hook for subclasses to clean up nodes after the transition happened. Furthermore this can be used from subclasses
* to manually perform deletions. * to manually perform deletions.
*/ */
@ -1257,9 +1270,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
#pragma mark _ASTransitionContextCompletionDelegate #pragma mark _ASTransitionContextCompletionDelegate
/* /**
* After completeTransition: is called on the ASContextTransitioning object in animateLayoutTransition: this * After completeTransition: is called on the ASContextTransitioning object in animateLayoutTransition: this
* delegate method will be called that start the completion process of the * delegate method will be called that start the completion process of the transition
*/ */
- (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete - (void)transitionContext:(_ASTransitionContext *)context didComplete:(BOOL)didComplete
{ {
@ -1267,6 +1280,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
_pendingLayoutTransitionContext = nil; _pendingLayoutTransitionContext = nil;
[self _pendingLayoutTransitionDidComplete]; [self _pendingLayoutTransitionDidComplete];
// Mark transaction as finished
[self _finishOrCancelTransition];
} }
#pragma mark - Layout #pragma mark - Layout

View File

@ -44,3 +44,9 @@
completionDelegate:(id<_ASTransitionContextCompletionDelegate>)completionDelegate; completionDelegate:(id<_ASTransitionContextCompletionDelegate>)completionDelegate;
@end @end
@interface _ASAnimatedTransitionContext : NSObject
@property (nonatomic, strong, readonly) ASDisplayNode *node;
@property (nonatomic, assign, readonly) CGFloat alpha;
+ (instancetype)contextForNode:(ASDisplayNode *)node alpha:(CGFloat)alphaValue;
@end

View File

@ -97,3 +97,21 @@ NSString * const ASTransitionContextToLayoutKey = @"org.asyncdisplaykit.ASTransi
} }
@end @end
@interface _ASAnimatedTransitionContext ()
@property (nonatomic, strong, readwrite) ASDisplayNode *node;
@property (nonatomic, assign, readwrite) CGFloat alpha;
@end
@implementation _ASAnimatedTransitionContext
+ (instancetype)contextForNode:(ASDisplayNode *)node alpha:(CGFloat)alpha
{
_ASAnimatedTransitionContext *context = [[_ASAnimatedTransitionContext alloc] init];
context.node = node;
context.alpha = alpha;
return context;
}
@end