mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-09 07:41:40 +00:00
Remove ASDisplayNode -shouldUseNewRenderingRange method and ASRangeControllerStable class
This commit is contained in:
parent
06bdcd0049
commit
5d474bcb1a
@ -495,10 +495,6 @@
|
||||
DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
DECBD6E91BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
|
||||
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
|
||||
DECC2ECD1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */ = {isa = PBXBuildFile; fileRef = DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */; };
|
||||
DECC2ECE1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */ = {isa = PBXBuildFile; fileRef = DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */; };
|
||||
DECC2ECF1C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */; };
|
||||
DECC2ED01C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -817,8 +813,6 @@
|
||||
DEC146B51C37A16A004A0EE7 /* ASCollectionInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASCollectionInternal.m; path = Details/ASCollectionInternal.m; sourceTree = "<group>"; };
|
||||
DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASButtonNode.h; sourceTree = "<group>"; };
|
||||
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNode.mm; sourceTree = "<group>"; };
|
||||
DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeControllerBeta.h; sourceTree = "<group>"; };
|
||||
DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeControllerBeta.mm; sourceTree = "<group>"; };
|
||||
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@ -1097,8 +1091,6 @@
|
||||
058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */,
|
||||
055F1A3619ABD413004DAFF1 /* ASRangeController.h */,
|
||||
055F1A3719ABD413004DAFF1 /* ASRangeController.mm */,
|
||||
DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */,
|
||||
DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */,
|
||||
292C599C1A956527007E5DD6 /* ASRangeHandler.h */,
|
||||
258FF4251C0D152600A83844 /* ASRangeHandlerVisible.h */,
|
||||
258FF4261C0D152600A83844 /* ASRangeHandlerVisible.mm */,
|
||||
@ -1399,7 +1391,6 @@
|
||||
9C65A72A1BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h in Headers */,
|
||||
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */,
|
||||
257754B61BEE44CD00737CA5 /* ASEqualityHashHelpers.h in Headers */,
|
||||
DECC2ECD1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */,
|
||||
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
|
||||
ACF6ED4D1B17847A00DA7C62 /* ASLayoutSpecUtilities.h in Headers */,
|
||||
AC026B6F1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */,
|
||||
@ -1462,7 +1453,6 @@
|
||||
B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
||||
B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */,
|
||||
B13CA1011C52004900E031AB /* ASCollectionNode+Beta.h in Headers */,
|
||||
DECC2ECE1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */,
|
||||
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */,
|
||||
B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */,
|
||||
B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */,
|
||||
@ -1853,7 +1843,6 @@
|
||||
257754BE1BEE458E00737CA5 /* ASTextKitHelpers.mm in Sources */,
|
||||
257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */,
|
||||
ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */,
|
||||
DECC2ECF1C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */,
|
||||
ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */,
|
||||
257754A61BEE44CD00737CA5 /* ASTextKitAttributes.mm in Sources */,
|
||||
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
|
||||
@ -1990,7 +1979,6 @@
|
||||
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
||||
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
||||
34EFC7761B701D2A00AD841F /* ASStackPositionedLayout.mm in Sources */,
|
||||
DECC2ED01C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */,
|
||||
34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */,
|
||||
AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */,
|
||||
34EFC7741B701D0A00AD841F /* ASStaticLayoutSpec.mm in Sources */,
|
||||
|
||||
@ -167,12 +167,9 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
self.strongCollectionNode = collectionNode;
|
||||
}
|
||||
|
||||
_layoutController = [ASDisplayNode shouldUseNewRenderingRange] ?
|
||||
[[ASCollectionViewLayoutControllerBeta alloc] initWithCollectionView:self] :
|
||||
[[ASCollectionViewLayoutControllerStable alloc] initWithCollectionView:self];
|
||||
_layoutController = [[ASCollectionViewLayoutControllerBeta alloc] initWithCollectionView:self];
|
||||
|
||||
_rangeController = [ASDisplayNode shouldUseNewRenderingRange] ? [[ASRangeControllerBeta alloc] init]
|
||||
: [[ASRangeControllerStable alloc] init];
|
||||
_rangeController = [[ASRangeControllerBeta alloc] init];
|
||||
_rangeController.dataSource = self;
|
||||
_rangeController.delegate = self;
|
||||
_rangeController.layoutController = _layoutController;
|
||||
|
||||
@ -8,9 +8,6 @@
|
||||
|
||||
@interface ASDisplayNode (Beta)
|
||||
|
||||
+ (BOOL)shouldUseNewRenderingRange;
|
||||
+ (void)setShouldUseNewRenderingRange:(BOOL)shouldUseNewRenderingRange;
|
||||
|
||||
+ (BOOL)usesImplicitHierarchyManagement;
|
||||
+ (void)setUsesImplicitHierarchyManagement:(BOOL)enabled;
|
||||
|
||||
|
||||
@ -256,7 +256,6 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
+ (void)scheduleNodeForRecursiveDisplay:(ASDisplayNode *)node
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert([ASDisplayNode shouldUseNewRenderingRange], @"+scheduleNodeForRecursiveDisplay: should never be called without the new rendering range enabled");
|
||||
static NSMutableSet *nodesToDisplay = nil;
|
||||
static BOOL displayScheduled = NO;
|
||||
static ASDN::RecursiveMutex displaySchedulerLock;
|
||||
@ -1666,18 +1665,6 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
||||
return _flags.shouldBypassEnsureDisplay;
|
||||
}
|
||||
|
||||
static BOOL ShouldUseNewRenderingRange = YES;
|
||||
|
||||
+ (BOOL)shouldUseNewRenderingRange
|
||||
{
|
||||
return ShouldUseNewRenderingRange;
|
||||
}
|
||||
|
||||
+ (void)setShouldUseNewRenderingRange:(BOOL)shouldUseNewRenderingRange
|
||||
{
|
||||
ShouldUseNewRenderingRange = shouldUseNewRenderingRange;
|
||||
}
|
||||
|
||||
#pragma mark - For Subclasses
|
||||
|
||||
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
|
||||
@ -1922,7 +1909,7 @@ static BOOL ShouldUseNewRenderingRange = YES;
|
||||
} else {
|
||||
// NOTE: This case isn't currently supported as setInterfaceState: isn't exposed externally, and all
|
||||
// internal use cases are range-managed. When a node is visible, don't mess with display - CA will start it.
|
||||
if ([ASDisplayNode shouldUseNewRenderingRange] && !ASInterfaceStateIncludesVisible(newState)) {
|
||||
if (!ASInterfaceStateIncludesVisible(newState)) {
|
||||
// Check __implementsDisplay purely for efficiency - it's faster even than calling -asyncLayer.
|
||||
if ([self __implementsDisplay]) {
|
||||
if (nowDisplay) {
|
||||
|
||||
@ -148,8 +148,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
{
|
||||
_layoutController = [[ASFlowLayoutController alloc] initWithScrollOption:ASFlowLayoutDirectionVertical];
|
||||
|
||||
_rangeController = [ASDisplayNode shouldUseNewRenderingRange] ? [[ASRangeControllerBeta alloc] init]
|
||||
: [[ASRangeControllerStable alloc] init];
|
||||
_rangeController = [[ASRangeControllerBeta alloc] init];
|
||||
_rangeController.layoutController = _layoutController;
|
||||
_rangeController.dataSource = self;
|
||||
_rangeController.delegate = self;
|
||||
|
||||
@ -19,9 +19,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
@interface ASCollectionViewLayoutControllerStable : ASCollectionViewLayoutController
|
||||
@end
|
||||
|
||||
@interface ASCollectionViewLayoutControllerBeta : ASCollectionViewLayoutController
|
||||
@end
|
||||
|
||||
|
||||
@ -51,86 +51,6 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASCollectionViewLayoutControllerStable
|
||||
{
|
||||
std::vector<CGRect> _updateRangeBoundsIndexedByRangeType;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView
|
||||
{
|
||||
if (!(self = [super initWithCollectionView:collectionView])) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_updateRangeBoundsIndexedByRangeType = std::vector<CGRect>(ASLayoutRangeTypeCount);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||
{
|
||||
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeMode:rangeMode rangeType:rangeType];
|
||||
ASRangeGeometry rangeGeometry = [self rangeGeometryWithScrollDirection:scrollDirection tuningParameters:tuningParameters];
|
||||
_updateRangeBoundsIndexedByRangeType[rangeType] = rangeGeometry.updateBounds;
|
||||
return [self indexPathsForItemsWithinRangeBounds:rangeGeometry.rangeBounds];
|
||||
}
|
||||
|
||||
- (NSSet *)indexPathsForItemsWithinRangeBounds:(CGRect)rangeBounds
|
||||
{
|
||||
NSMutableSet *indexPathSet = [[NSMutableSet alloc] init];
|
||||
NSArray *layoutAttributes = [_collectionViewLayout layoutAttributesForElementsInRect:rangeBounds];
|
||||
for (UICollectionViewLayoutAttributes *la in layoutAttributes) {
|
||||
if (la.representedElementCategory == UICollectionElementCategoryCell) {
|
||||
[indexPathSet addObject:la.indexPath];
|
||||
}
|
||||
}
|
||||
return indexPathSet;
|
||||
}
|
||||
|
||||
- (ASRangeGeometry)rangeGeometryWithScrollDirection:(ASScrollDirection)scrollDirection
|
||||
tuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||
{
|
||||
CGRect rangeBounds = _collectionView.bounds;
|
||||
CGRect updateBounds = _collectionView.bounds;
|
||||
|
||||
// Scrollable directions can change for non-flow layouts
|
||||
if ([_collectionViewLayout asdk_isFlowLayout] == NO) {
|
||||
_scrollableDirections = [_collectionView scrollableDirections];
|
||||
}
|
||||
|
||||
rangeBounds = CGRectExpandToRangeWithScrollableDirections(rangeBounds, tuningParameters, _scrollableDirections, scrollDirection);
|
||||
|
||||
ASRangeTuningParameters updateTuningParameters = tuningParameters;
|
||||
updateTuningParameters.leadingBufferScreenfuls = MIN(updateTuningParameters.leadingBufferScreenfuls * 0.5, 0.95);
|
||||
updateTuningParameters.trailingBufferScreenfuls = MIN(updateTuningParameters.trailingBufferScreenfuls * 0.5, 0.95);
|
||||
|
||||
updateBounds = CGRectExpandToRangeWithScrollableDirections(updateBounds, updateTuningParameters, _scrollableDirections, scrollDirection);
|
||||
|
||||
return {rangeBounds, updateBounds};
|
||||
}
|
||||
|
||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths rangeType:(ASLayoutRangeType)rangeType
|
||||
{
|
||||
CGSize viewportSize = [self viewportSize];
|
||||
CGRect updateRangeBounds = _updateRangeBoundsIndexedByRangeType[rangeType];
|
||||
if (CGRectIsEmpty(updateRangeBounds)) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
CGRect currentBounds = _collectionView.bounds;
|
||||
if (CGRectIsEmpty(currentBounds)) {
|
||||
currentBounds = CGRectMake(0, 0, viewportSize.width, viewportSize.height);
|
||||
}
|
||||
|
||||
if (CGRectContainsRect(updateRangeBounds, currentBounds)) {
|
||||
return NO;
|
||||
} else {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ASCollectionViewLayoutControllerBeta
|
||||
|
||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||
|
||||
@ -77,9 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
@interface ASRangeControllerStable : ASRangeController
|
||||
@end
|
||||
|
||||
@interface ASRangeControllerBeta : ASRangeController
|
||||
@end
|
||||
|
||||
|
||||
@ -38,243 +38,4 @@
|
||||
return [_layoutController tuningParametersForRangeMode:rangeMode rangeType:rangeType];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface ASRangeControllerStable ()
|
||||
{
|
||||
BOOL _rangeIsValid;
|
||||
|
||||
// keys should be ASLayoutRangeTypes and values NSSets containing NSIndexPaths
|
||||
NSMutableDictionary *_rangeTypeIndexPaths;
|
||||
NSDictionary *_rangeTypeHandlers;
|
||||
BOOL _queuedRangeUpdate;
|
||||
|
||||
ASScrollDirection _scrollDirection;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASRangeControllerStable
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (!(self = [super init])) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_rangeIsValid = YES;
|
||||
_rangeTypeIndexPaths = [NSMutableDictionary dictionary];
|
||||
_rangeTypeHandlers = @{
|
||||
@(ASLayoutRangeTypeDisplay) : [[ASRangeHandlerRender alloc] init],
|
||||
@(ASLayoutRangeTypeFetchData): [[ASRangeHandlerPreload alloc] init],
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Cell node view handling
|
||||
|
||||
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)node
|
||||
{
|
||||
if (node.view.superview == contentView) {
|
||||
// this content view is already correctly configured
|
||||
return;
|
||||
}
|
||||
|
||||
// clean the content view
|
||||
for (UIView *view in contentView.subviews) {
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
|
||||
[self moveCellNode:node toView:contentView];
|
||||
}
|
||||
|
||||
- (void)moveCellNode:(ASCellNode *)node toView:(UIView *)view
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(node, @"Cannot move a nil node to a view");
|
||||
ASDisplayNodeAssert(view, @"Cannot move a node to a non-existent view");
|
||||
|
||||
// force any nodes that are about to come into view to have display enabled
|
||||
if (node.displaySuspended) {
|
||||
[node recursivelySetDisplaySuspended:NO];
|
||||
}
|
||||
|
||||
[view addSubview:node.view];
|
||||
}
|
||||
|
||||
#pragma mark - Core visible node range managment API
|
||||
|
||||
- (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection
|
||||
{
|
||||
_scrollDirection = scrollDirection;
|
||||
|
||||
if (_queuedRangeUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// coalesce these events -- handling them multiple times per runloop is noisy and expensive
|
||||
_queuedRangeUpdate = YES;
|
||||
|
||||
[self performSelector:@selector(_updateVisibleNodeIndexPaths)
|
||||
withObject:nil
|
||||
afterDelay:0
|
||||
inModes:@[ NSRunLoopCommonModes ]];
|
||||
}
|
||||
|
||||
- (void)_updateVisibleNodeIndexPaths
|
||||
{
|
||||
if (!_queuedRangeUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray *visibleNodePaths = [_dataSource visibleNodeIndexPathsForRangeController:self];
|
||||
|
||||
if (visibleNodePaths.count == 0) { // if we don't have any visibleNodes currently (scrolled before or after content)...
|
||||
_queuedRangeUpdate = NO;
|
||||
return ; // don't do anything for this update, but leave _rangeIsValid to make sure we update it later
|
||||
}
|
||||
|
||||
NSSet *visibleNodePathsSet = [NSSet setWithArray:visibleNodePaths];
|
||||
CGSize viewportSize = [_dataSource viewportSizeForRangeController:self];
|
||||
[_layoutController setViewportSize:viewportSize];
|
||||
|
||||
// the layout controller needs to know what the current visible indices are to calculate range offsets
|
||||
if ([_layoutController respondsToSelector:@selector(setVisibleNodeIndexPaths:)]) {
|
||||
[_layoutController setVisibleNodeIndexPaths:visibleNodePaths];
|
||||
}
|
||||
|
||||
for (NSInteger i = 0; i < ASLayoutRangeTypeCount; i++) {
|
||||
ASLayoutRangeType rangeType = (ASLayoutRangeType)i;
|
||||
id rangeKey = @(rangeType);
|
||||
|
||||
// this delegate decide what happens when a node is added or removed from a range
|
||||
id<ASRangeHandler> rangeHandler = _rangeTypeHandlers[rangeKey];
|
||||
|
||||
if (!_rangeIsValid || [_layoutController shouldUpdateForVisibleIndexPaths:visibleNodePaths rangeType:rangeType]) {
|
||||
NSSet *indexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
||||
rangeMode:ASLayoutRangeModeFull
|
||||
rangeType:rangeType];
|
||||
|
||||
// Notify to remove indexpaths that are leftover that are not visible or included in the _layoutController calculated paths
|
||||
NSMutableSet *removedIndexPaths = _rangeIsValid ? [_rangeTypeIndexPaths[rangeKey] mutableCopy] : [NSMutableSet set];
|
||||
[removedIndexPaths minusSet:indexPaths];
|
||||
[removedIndexPaths minusSet:visibleNodePathsSet];
|
||||
|
||||
if (removedIndexPaths.count) {
|
||||
NSArray *removedNodes = [_dataSource rangeController:self nodesAtIndexPaths:[removedIndexPaths allObjects]];
|
||||
for (ASCellNode *node in removedNodes) {
|
||||
// since this class usually manages large or infinite data sets, the working range
|
||||
// directly bounds memory usage by requiring redrawing any content that falls outside the range.
|
||||
[rangeHandler node:node exitedRangeOfType:rangeType];
|
||||
}
|
||||
}
|
||||
|
||||
// Notify to add index paths that are not currently in _rangeTypeIndexPaths
|
||||
NSMutableSet *addedIndexPaths = [indexPaths mutableCopy];
|
||||
[addedIndexPaths minusSet:_rangeTypeIndexPaths[rangeKey]];
|
||||
|
||||
// The preload range (for example) should include nodes that are visible
|
||||
// TODO: remove this once we have removed the dependency on Core Animation's -display
|
||||
if ([self shouldSkipVisibleNodesForRangeType:rangeType]) {
|
||||
[addedIndexPaths minusSet:visibleNodePathsSet];
|
||||
}
|
||||
|
||||
if (addedIndexPaths.count) {
|
||||
NSArray *addedNodes = [_dataSource rangeController:self nodesAtIndexPaths:[addedIndexPaths allObjects]];
|
||||
for (ASCellNode *node in addedNodes) {
|
||||
[rangeHandler node:node enteredRangeOfType:rangeType];
|
||||
}
|
||||
}
|
||||
|
||||
// set the range indexpaths so that we can remove/add on the next update pass
|
||||
_rangeTypeIndexPaths[rangeKey] = indexPaths;
|
||||
}
|
||||
}
|
||||
|
||||
_rangeIsValid = YES;
|
||||
_queuedRangeUpdate = NO;
|
||||
}
|
||||
|
||||
- (BOOL)shouldSkipVisibleNodesForRangeType:(ASLayoutRangeType)rangeType
|
||||
{
|
||||
return rangeType == ASLayoutRangeTypeDisplay;
|
||||
}
|
||||
|
||||
#pragma mark - ASDataControllerDelegete
|
||||
|
||||
- (void)dataControllerBeginUpdates:(ASDataController *)dataController
|
||||
{
|
||||
ASPerformBlockOnMainThread(^{
|
||||
[_delegate didBeginUpdatesInRangeController:self];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController endUpdatesAnimated:(BOOL)animated completion:(void (^)(BOOL))completion
|
||||
{
|
||||
ASPerformBlockOnMainThread(^{
|
||||
[_delegate rangeController:self didEndUpdatesAnimated:animated completion:completion];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASDisplayNodeAssert(nodes.count == indexPaths.count, @"Invalid index path");
|
||||
ASPerformBlockOnMainThread(^{
|
||||
_rangeIsValid = NO;
|
||||
[_delegate rangeController:self didInsertNodes:nodes atIndexPaths:indexPaths withAnimationOptions:animationOptions];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASPerformBlockOnMainThread(^{
|
||||
_rangeIsValid = NO;
|
||||
|
||||
// When removing nodes we need to make sure that removed indexPaths are not left in _rangeTypeIndexPaths,
|
||||
// otherwise _updateVisibleNodeIndexPaths may try to retrieve nodes from dataSource that aren't there anymore
|
||||
for (NSInteger i = 0; i < ASLayoutRangeTypeCount; i++) {
|
||||
id rangeKey = @((ASLayoutRangeType)i);
|
||||
NSMutableSet *rangePaths = [_rangeTypeIndexPaths[rangeKey] mutableCopy];
|
||||
for (NSIndexPath *path in indexPaths) {
|
||||
[rangePaths removeObject:path];
|
||||
}
|
||||
_rangeTypeIndexPaths[rangeKey] = rangePaths;
|
||||
}
|
||||
|
||||
[_delegate rangeController:self didDeleteNodes:nodes atIndexPaths:indexPaths withAnimationOptions:animationOptions];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASDisplayNodeAssert(sections.count == indexSet.count, @"Invalid sections");
|
||||
ASPerformBlockOnMainThread(^{
|
||||
_rangeIsValid = NO;
|
||||
[_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet withAnimationOptions:animationOptions];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASPerformBlockOnMainThread(^{
|
||||
_rangeIsValid = NO;
|
||||
|
||||
// When removing nodes we need to make sure that removed indexPaths are not left in _rangeTypeIndexPaths,
|
||||
// otherwise _updateVisibleNodeIndexPaths may try to retrieve nodes from dataSource that aren't there anymore
|
||||
for (NSInteger i = 0; i < ASLayoutRangeTypeCount; i++) {
|
||||
id rangeKey = @((ASLayoutRangeType)i);
|
||||
NSMutableSet *rangePaths = [_rangeTypeIndexPaths[rangeKey] mutableCopy];
|
||||
for (NSIndexPath *path in _rangeTypeIndexPaths[rangeKey]) {
|
||||
if ([indexSet containsIndex:path.section]) {
|
||||
[rangePaths removeObject:path];
|
||||
}
|
||||
}
|
||||
_rangeTypeIndexPaths[rangeKey] = rangePaths;
|
||||
}
|
||||
|
||||
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOptions:animationOptions];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
@ -18,36 +18,6 @@
|
||||
@end
|
||||
|
||||
@implementation ASRangeHandlerRender
|
||||
@synthesize workingWindow = _workingWindow;
|
||||
|
||||
- (UIWindow *)workingWindow
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
// we add nodes' views to this invisible window to start async rendering
|
||||
// TODO: Replace this with directly triggering display https://github.com/facebook/AsyncDisplayKit/issues/315
|
||||
// Update: Latest attempt is at https://github.com/facebook/AsyncDisplayKit/pull/828
|
||||
|
||||
if (!_workingWindow && ![ASDisplayNode shouldUseNewRenderingRange]) {
|
||||
_workingWindow = [[UIWindow alloc] initWithFrame:CGRectZero];
|
||||
_workingWindow.windowLevel = UIWindowLevelNormal - 1000;
|
||||
_workingWindow.userInteractionEnabled = NO;
|
||||
_workingWindow.hidden = YES;
|
||||
_workingWindow.alpha = 0.0;
|
||||
}
|
||||
|
||||
return _workingWindow;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (![ASDisplayNode shouldUseNewRenderingRange]) {
|
||||
for (CALayer *layer in [self.workingWindow.layer.sublayers copy]) {
|
||||
ASDisplayNode *node = layer.asyncdisplaykit_node;
|
||||
[self node:node exitedRangeOfType:ASLayoutRangeTypeDisplay];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType
|
||||
{
|
||||
@ -65,16 +35,7 @@
|
||||
|
||||
|
||||
// ASDisplayNodeAssert(![ASDisplayNode shouldUseNewRenderingRange], @"It should no longer be possible to reach this point with the new display range enabled");
|
||||
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
||||
[node recursivelyEnsureDisplaySynchronously:NO];
|
||||
} else {
|
||||
// Add the node's layer to an off-screen window to trigger display and mark its contents as non-volatile.
|
||||
// Use the layer directly to avoid the substantial overhead of UIView heirarchy manipulations.
|
||||
// Any view-backed nodes will still create their views in order to assemble the layer heirarchy, and they will
|
||||
// also assemble a view subtree for the node, but we avoid the much more significant expense triggered by a view
|
||||
// being added or removed from an onscreen window (responder chain setup, will/DidMoveToWindow: recursive calls, etc)
|
||||
[[[self workingWindow] layer] addSublayer:node.layer];
|
||||
}
|
||||
[node recursivelyEnsureDisplaySynchronously:NO];
|
||||
}
|
||||
|
||||
- (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType
|
||||
@ -103,24 +64,9 @@
|
||||
[node exitInterfaceState:ASInterfaceStateDisplay];
|
||||
|
||||
// ASDisplayNodeAssert(![ASDisplayNode shouldUseNewRenderingRange], @"It should no longer be possible to reach this point with the new display range enabled");
|
||||
|
||||
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
||||
if (![node isLayerBacked]) {
|
||||
[node.view removeFromSuperview];
|
||||
} else {
|
||||
[node.layer removeFromSuperlayer];
|
||||
}
|
||||
if (![node isLayerBacked]) {
|
||||
[node.view removeFromSuperview];
|
||||
} else {
|
||||
if (node.layer.superlayer != [[self workingWindow] layer]) {
|
||||
// In this case, the node has previously passed through the working range (or it is zero), and it has now fallen outside the working range.
|
||||
if (![node isLayerBacked]) {
|
||||
// If the node is view-backed, we need to make sure to remove the view (which is now present in the containing cell contentsView).
|
||||
// Layer-backed nodes will be fully handled by the unconditional removal below.
|
||||
[node.view removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, the node's layer may validly be present either in the workingWindow, or in the contentsView of a cell.
|
||||
[node.layer removeFromSuperlayer];
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,13 +290,11 @@
|
||||
|
||||
_messageToViewOrLayer(setNeedsDisplay);
|
||||
|
||||
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
||||
BOOL nowDisplay = ASInterfaceStateIncludesDisplay(_interfaceState);
|
||||
// FIXME: This should not need to recursively display, so create a non-recursive variant.
|
||||
// The semantics of setNeedsDisplay (as defined by CALayer behavior) are not recursive.
|
||||
if (_layer && !_flags.synchronous && nowDisplay && [self __implementsDisplay]) {
|
||||
[ASDisplayNode scheduleNodeForRecursiveDisplay:self];
|
||||
}
|
||||
BOOL nowDisplay = ASInterfaceStateIncludesDisplay(_interfaceState);
|
||||
// FIXME: This should not need to recursively display, so create a non-recursive variant.
|
||||
// The semantics of setNeedsDisplay (as defined by CALayer behavior) are not recursive.
|
||||
if (_layer && !_flags.synchronous && nowDisplay && [self __implementsDisplay]) {
|
||||
[ASDisplayNode scheduleNodeForRecursiveDisplay:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[ASDisplayNode setShouldUseNewRenderingRange:YES];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user