Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions AsyncDisplayKit/ASDisplayNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,10 @@ - (void)addSubnode:(ASDisplayNode *)subnode
_subnodes = [[NSMutableArray alloc] init];

[_subnodes addObject:subnode];

// 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];

if (self.nodeLoaded) {
// If this node has a view or layer, force the subnode to also create its view or layer and add it to the hierarchy here.
Expand All @@ -969,8 +973,6 @@ - (void)addSubnode:(ASDisplayNode *)subnode
if (isMovingEquivalentParents) {
[subnode __decrementVisibilityNotificationsDisabled];
}

[subnode __setSupernode:self];
}

/*
Expand Down Expand Up @@ -1267,7 +1269,7 @@ - (void)__decrementVisibilityNotificationsDisabled
}

// This uses the layer hieararchy for safety. Who knows what people might do and it would be bad to have visibilty out of sync
- (BOOL)__hasParentWithVisibilityNotificationsDisabled
- (BOOL)__selfOrParentHasVisibilityNotificationsDisabled
{
CALayer *layer = _layer;
do {
Expand All @@ -1287,7 +1289,7 @@ - (void)__enterHierarchy
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"Should not cause recursive __enterHierarchy");
if (!self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) {
if (!self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __selfOrParentHasVisibilityNotificationsDisabled]) {
self.inHierarchy = YES;
_flags.isEnteringHierarchy = YES;
if (self.shouldRasterizeDescendants) {
Expand All @@ -1309,7 +1311,7 @@ - (void)__exitHierarchy
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"Should not cause recursive __exitHierarchy");
if (self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) {
if (self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __selfOrParentHasVisibilityNotificationsDisabled]) {
self.inHierarchy = NO;

[self.asyncLayer cancelAsyncDisplay];
Expand Down Expand Up @@ -1807,6 +1809,19 @@ - (void)setHierarchyState:(ASHierarchyState)newState
_hierarchyState = newState;
}

// Entered or exited contents rendering state.
if ((newState & ASHierarchyStateRangeManaged) != (oldState & ASHierarchyStateRangeManaged)) {
if (newState & ASHierarchyStateRangeManaged) {
[self enterInterfaceState:self.supernode.interfaceState];
} else {
// The case of exiting a range-managed state should be fairly rare. Adding or removing the node
// to a view hierarchy will cause its interfaceState to be either fully set or unset (all fields),
// but because we might be about to be added to a view hierarchy, exiting the interface state now
// would cause inefficient churn. The tradeoff is that we may not clear contents / fetched data
// for nodes that are removed from a managed state and then retained but not used (bad idea anyway!)
}
}

if (newState != oldState) {
LOG(@"setHierarchyState: oldState = %lu, newState = %lu", (unsigned long)oldState, (unsigned long)newState);
}
Expand Down