Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 9264496

Browse files
committed
Merge pull request #1005 from facebook/ASDisplayNodeContentsPreservation
[ASDisplayNode] Preserve contents after non-range-managed nodes are removed from superviews or windows.
2 parents e56315d + 55861b3 commit 9264496

2 files changed

Lines changed: 20 additions & 8 deletions

File tree

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,23 +1770,31 @@ - (void)setInterfaceState:(ASInterfaceState)newState
17701770
// Trigger asynchronous measurement if it is not already cached or being calculated.
17711771
}
17721772

1773+
// For the FetchData and Display ranges, we don't want to call -clear* if not being managed by a range controller.
1774+
// Otherwise we get flashing behavior from normal UIKit manipulations like navigation controller push / pop.
1775+
// Still, the interfaceState should be updated to the current state of the node; just don't act on the transition.
1776+
17731777
// Entered or exited data loading state.
17741778
if ((newState & ASInterfaceStateFetchData) != (oldState & ASInterfaceStateFetchData)) {
17751779
if (newState & ASInterfaceStateFetchData) {
17761780
[self fetchData];
17771781
} else {
1778-
[self clearFetchedData];
1782+
if ([self supportsRangeManagedInterfaceState]) {
1783+
[self clearFetchedData];
1784+
}
17791785
}
17801786
}
17811787

17821788
// Entered or exited contents rendering state.
17831789
if ((newState & ASInterfaceStateDisplay) != (oldState & ASInterfaceStateDisplay)) {
1784-
if (newState & ASInterfaceStateDisplay) {
1785-
// Once the working window is eliminated (ASRangeHandlerRender), trigger display directly here.
1786-
[self setDisplaySuspended:NO];
1787-
} else {
1788-
[self setDisplaySuspended:YES];
1789-
[self clearContents];
1790+
if ([self supportsRangeManagedInterfaceState]) {
1791+
if (newState & ASInterfaceStateDisplay) {
1792+
// Once the working window is eliminated (ASRangeHandlerRender), trigger display directly here.
1793+
[self setDisplaySuspended:NO];
1794+
} else {
1795+
[self setDisplaySuspended:YES];
1796+
[self clearContents];
1797+
}
17901798
}
17911799
}
17921800

AsyncDisplayKitTests/ASDisplayNodeTests.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1702,7 +1702,11 @@ - (void)testInterfaceStateForNonCellNode
17021702
XCTAssert(node.interfaceState == ASInterfaceStateInHierarchy);
17031703

17041704
[node.view removeFromSuperview];
1705-
XCTAssert(!node.hasFetchedData);
1705+
// We don't want to call -clearFetchedData on nodes that aren't being managed by a range controller.
1706+
// Otherwise we get flashing behavior from normal UIKit manipulations like navigation controller push / pop.
1707+
// Still, the interfaceState should be None to reflect the current state of the node.
1708+
// We just don't proactively clear contents or fetched data for this state transition.
1709+
XCTAssert(node.hasFetchedData);
17061710
XCTAssert(node.interfaceState == ASInterfaceStateNone);
17071711
}
17081712

0 commit comments

Comments
 (0)