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 {