Skip to content

Commit

Permalink
[ASDisplayNode] Propagate traits before loading a subnode
Browse files Browse the repository at this point in the history
#886 enforces that some nodes are loaded before they are sent a visiblity event, but it was not propagating the trait collection before forcing the load.

We are propagating traits in `_setSupernode:` (which was happening after the forced load). I moved the possible forced load to `_setSupernode:`, after propagating traits but before any visibility states are changed.
  • Loading branch information
rcancro committed Nov 14, 2018
1 parent 8029632 commit f24bf80
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions Source/ASDisplayNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2139,6 +2139,18 @@ - (void)_setSupernode:(ASDisplayNode *)newSupernode
stateToEnterOrExit |= ASHierarchyStateRasterized;
}
if (newSupernode) {

// Now that we have a supernode, propagate its traits to self.
// This should be done before possibly forcing self to load so we have traits in -didLoad
ASTraitCollectionPropagateDown(self, newSupernode.primitiveTraitCollection);

if (!parentWasOrIsRasterized && newSupernode.nodeLoaded) {
// Trigger the subnode to load its layer, which will create its view if it needs one.
// By doing this prior to the downward propagation of newSupernode's interface state,
// we can guarantee that -didEnterVisibleState is only called with .isNodeLoaded = YES.
[self layer];
}

[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
Expand All @@ -2158,10 +2170,6 @@ - (void)_setSupernode:(ASDisplayNode *)newSupernode
}
}
}

// Now that we have a supernode, propagate its traits to self.
ASTraitCollectionPropagateDown(self, newSupernode.primitiveTraitCollection);

} 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
Expand Down Expand Up @@ -2260,13 +2268,6 @@ - (void)_insertSubnode:(ASDisplayNode *)subnode atSubnodeIndex:(NSInteger)subnod
_cachedSubnodes = nil;
__instanceLock__.unlock();

if (!isRasterized && self.nodeLoaded) {
// Trigger the subnode to load its layer, which will create its view if it needs one.
// By doing this prior to downward propagation of .interfaceState in _setSupernode:,
// we can guarantee that -didEnterVisibleState is only called with .isNodeLoaded = YES.
[subnode layer];
}

// This call will apply our .hierarchyState to the new subnode.
// If we are a managed hierarchy, as in ASCellNode trees, it will also apply our .interfaceState.
[subnode _setSupernode:self];
Expand Down

0 comments on commit f24bf80

Please sign in to comment.