diff --git a/Source/ASCollectionView.mm b/Source/ASCollectionView.mm index b80da85571..6c1e04edfa 100644 --- a/Source/ASCollectionView.mm +++ b/Source/ASCollectionView.mm @@ -2276,15 +2276,23 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier"; { BOOL visible = (self.window != nil); ASDisplayNode *node = self.collectionNode; + BOOL rangeControllerNeedsUpdate = ![node supportsRangeManagedInterfaceState];; + if (!visible && node.inHierarchy) { + if (rangeControllerNeedsUpdate) { + rangeControllerNeedsUpdate = NO; + // Exit CellNodes first before Collection to match UIKit behaviors (tear down bottom up). + // Although we have not yet cleared the interfaceState's Visible bit (this happens in __exitHierarchy), + // the ASRangeController will get the correct value from -interfaceStateForRangeController:. + [_rangeController updateRanges]; + } [node __exitHierarchy]; } // Updating the visible node index paths only for not range managed nodes. Range managed nodes will get their // their update in the layout pass - if (![node supportsRangeManagedInterfaceState]) { - [_rangeController setNeedsUpdate]; - [_rangeController updateIfNeeded]; + if (rangeControllerNeedsUpdate) { + [_rangeController updateRanges]; } // When we aren't visible, we will only fetch up to the visible area. Now that we are visible, diff --git a/Source/ASTableView.mm b/Source/ASTableView.mm index 273bca46f3..7074bbcbfa 100644 --- a/Source/ASTableView.mm +++ b/Source/ASTableView.mm @@ -1907,15 +1907,23 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; { BOOL visible = (self.window != nil); ASDisplayNode *node = self.tableNode; + BOOL rangeControllerNeedsUpdate = ![node supportsRangeManagedInterfaceState];; + if (!visible && node.inHierarchy) { + if (rangeControllerNeedsUpdate) { + rangeControllerNeedsUpdate = NO; + // Exit CellNodes first before Table to match UIKit behaviors (tear down bottom up). + // Although we have not yet cleared the interfaceState's Visible bit (this happens in __exitHierarchy), + // the ASRangeController will get the correct value from -interfaceStateForRangeController:. + [_rangeController updateRanges]; + } [node __exitHierarchy]; } // Updating the visible node index paths only for not range managed nodes. Range managed nodes will get their // their update in the layout pass - if (![node supportsRangeManagedInterfaceState]) { - [_rangeController setNeedsUpdate]; - [_rangeController updateIfNeeded]; + if (rangeControllerNeedsUpdate) { + [_rangeController updateRanges]; } // When we aren't visible, we will only fetch up to the visible area. Now that we are visible, diff --git a/Source/Details/ASRangeController.h b/Source/Details/ASRangeController.h index 6e65b841b0..d9537c0d07 100644 --- a/Source/Details/ASRangeController.h +++ b/Source/Details/ASRangeController.h @@ -64,6 +64,11 @@ AS_SUBCLASSING_RESTRICTED */ - (void)updateIfNeeded; +/** + * Force update the ranges immediately. + */ +- (void)updateRanges; + /** * Add the sized node for `indexPath` as a subview of `contentView`. * diff --git a/Source/Details/ASRangeController.mm b/Source/Details/ASRangeController.mm index 3bb4044289..abd56cc361 100644 --- a/Source/Details/ASRangeController.mm +++ b/Source/Details/ASRangeController.mm @@ -154,12 +154,16 @@ static UIApplicationState __ApplicationState = UIApplicationStateActive; - (void)updateIfNeeded { if (_needsRangeUpdate) { - _needsRangeUpdate = NO; - - [self _updateVisibleNodeIndexPaths]; + [self updateRanges]; } } +- (void)updateRanges +{ + _needsRangeUpdate = NO; + [self _updateVisibleNodeIndexPaths]; +} + - (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode { _preserveCurrentRangeMode = YES; @@ -376,7 +380,7 @@ static UIApplicationState __ApplicationState = UIApplicationStateActive; [newVisibleNodes addObject:node]; } // Skip the many method calls of the recursive operation if the top level cell node already has the right interfaceState. - if (node.interfaceState != interfaceState) { + if (node.pendingInterfaceState != interfaceState) { #if ASRangeControllerLoggingEnabled [modifiedIndexPaths addObject:indexPath]; #endif