From 3a1a987dbeb7f955c9b7f7c511ea1ba5e58446a1 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Mon, 1 Aug 2016 09:44:02 -0700 Subject: [PATCH] Fix not propagating updating and propagating down the layout transition id if a subnode is added (#2018) If a node was added to a supernode, the supernode could be in a layout pending state. All of the hierarchy state properties related to the transition need to be copied over as well as propagated down the subtree. This is especially important as with Implicit Hierarchy Management adding subnodes can happen while a transition is in fly --- AsyncDisplayKit/ASDisplayNode.mm | 33 +++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 9dc3b2c2c3..0b56764e6e 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -1877,6 +1877,28 @@ static NSInteger incrementIfFound(NSInteger i) { } if (newSupernode) { [self enterHierarchyState:stateToEnterOrExit]; + + // If a node was added to a supernode, the supernode could be in a layout pending state. All of the hierarchy state + // properties related to the transition need to be copied over as well as propagated down the subtree. + // This is especially important as with Implicit Hierarchy Management adding subnodes can happen while a transition + // is in fly + if (ASHierarchyStateIncludesLayoutPending(stateToEnterOrExit)) { + int32_t pendingTransitionId = newSupernode.pendingTransitionID; + if (pendingTransitionId != ASLayoutableContextInvalidTransitionID) { + { + ASDN::MutexLocker l(__instanceLock__); + _pendingTransitionID = pendingTransitionId; + + // Propagate down the new pending transition id + ASDisplayNodePerformBlockOnEverySubnode(self, ^(ASDisplayNode * _Nonnull node) { + node.pendingTransitionID = _pendingTransitionID; + }); + } + } + } + + // Now that we have a supernode, propagate its traits to self. + ASEnvironmentStatePropagateDown(self, [newSupernode environmentTraitCollection]); } else { // If a node will be removed from the supernode it should go out from the layout pending state to remove all // layout pending state related properties on the node @@ -1884,11 +1906,6 @@ static NSInteger incrementIfFound(NSInteger i) { [self exitHierarchyState:stateToEnterOrExit]; } - - // now that we have a supernode, propagate its traits to self. - if (newSupernode != nil) { - ASEnvironmentStatePropagateDown(self, [newSupernode environmentTraitCollection]); - } } } @@ -2160,6 +2177,12 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) ASDisplayNodeAssertTrue(_pendingTransitionID < pendingTransitionID); _pendingTransitionID = pendingTransitionID; } + +- (int32_t)pendingTransitionID +{ + ASDN::MutexLocker l(__instanceLock__); + return _pendingTransitionID; +} - (void)setPreferredFrameSize:(CGSize)preferredFrameSize {