Skip to content

Commit 4dbd699

Browse files
committed
Fix bug in ASRangeController that causes some cell nodes of a collection view which is about to becomes invisible to load their backing view/layer and render (#1418)
1 parent ae2b3af commit 4dbd699

5 files changed

Lines changed: 25 additions & 16 deletions

File tree

Schemas/configuration.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"exp_disable_a11y_cache",
2626
"exp_dispatch_apply",
2727
"exp_image_downloader_priority",
28-
"exp_text_drawing"
28+
"exp_text_drawing",
29+
"exp_fix_range_controller"
2930
]
3031
}
3132
}

Source/ASExperimentalFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) {
3131
ASExperimentalDispatchApply = 1 << 10, // exp_dispatch_apply
3232
ASExperimentalImageDownloaderPriority = 1 << 11, // exp_image_downloader_priority
3333
ASExperimentalTextDrawing = 1 << 12, // exp_text_drawing
34+
ASExperimentalFixRangeController = 1 << 13, // exp_fix_range_controller
3435
ASExperimentalFeatureAll = 0xFFFFFFFF
3536
};
3637

Source/ASExperimentalFeatures.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
@"exp_disable_a11y_cache",
2525
@"exp_dispatch_apply",
2626
@"exp_image_downloader_priority",
27-
@"exp_text_drawing"]));
27+
@"exp_text_drawing",
28+
@"exp_fix_range_controller"]));
2829
if (flags == ASExperimentalFeatureAll) {
2930
return allNames;
3031
}

Source/Details/ASRangeController.mm

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -349,21 +349,25 @@ - (void)_updateVisibleNodeIndexPaths
349349
}
350350
}
351351
} else {
352-
// If selfInterfaceState isn't visible, then visibleIndexPaths represents what /will/ be immediately visible at the
353-
// instant we come onscreen. So, preload and display all of those things, but don't waste resources preloading yet.
354-
// We handle this as a separate case to minimize set operations for offscreen preloading, including containsObject:.
352+
// If selfInterfaceState isn't visible, then visibleIndexPaths represents either what /will/ be immediately visible at the
353+
// instant we come onscreen, or what /will/ no longer be visible at the instant we come offscreen.
354+
// So, preload and display all of those things, but don't waste resources preloading others.
355+
// We handle this as a separate case to minimize set operations, including -containsObject:.
356+
//
357+
// DO NOT set Visible: even though these elements are in the visible range / "viewport",
358+
// our overall container object is itself not yet, or no longer, visible.
359+
// The moment it becomes visible, we will run the condition above.
360+
361+
BOOL shouldUpdateInterfaceState = NO;
362+
if (ASActivateExperimentalFeature(ASExperimentalFixRangeController)) {
363+
shouldUpdateInterfaceState = [visibleIndexPaths containsObject:indexPath];
364+
} else {
365+
shouldUpdateInterfaceState = [allCurrentIndexPaths containsObject:indexPath];
366+
}
355367

356-
if ([allCurrentIndexPaths containsObject:indexPath]) {
357-
// DO NOT set Visible: even though these elements are in the visible range / "viewport",
358-
// our overall container object is itself not visible yet. The moment it becomes visible, we will run the condition above
359-
360-
// Set Layout, Preload
368+
if (shouldUpdateInterfaceState) {
361369
interfaceState |= ASInterfaceStatePreload;
362-
363370
if (rangeMode != ASLayoutRangeModeLowMemory) {
364-
// Add Display.
365-
// We might be looking at an indexPath that was previously in-range, but now we need to clear it.
366-
// In that case we'll just set it back to MeasureLayout. Only set Display | Preload if in allCurrentIndexPaths.
367371
interfaceState |= ASInterfaceStateDisplay;
368372
}
369373
}

Tests/ASConfigurationTests.mm

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
ASExperimentalDisableAccessibilityCache,
3131
ASExperimentalDispatchApply,
3232
ASExperimentalImageDownloaderPriority,
33-
ASExperimentalTextDrawing
33+
ASExperimentalTextDrawing,
34+
ASExperimentalFixRangeController
3435
};
3536

3637
@interface ASConfigurationTests : ASTestCase <ASConfigurationDelegate>
@@ -55,7 +56,8 @@ + (NSArray *)names {
5556
@"exp_disable_a11y_cache",
5657
@"exp_dispatch_apply",
5758
@"exp_image_downloader_priority",
58-
@"exp_text_drawing"
59+
@"exp_text_drawing",
60+
@"exp_fix_range_controller"
5961
];
6062
}
6163

0 commit comments

Comments
 (0)