Remove ASDisplayNode -shouldUseNewRenderingRange method and ASRangeControllerStable class

This commit is contained in:
Michael Schneider 2016-02-07 14:17:42 -08:00
parent 06bdcd0049
commit 5d474bcb1a
12 changed files with 13 additions and 427 deletions

View File

@ -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 */,

View File

@ -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;

View File

@ -8,9 +8,6 @@
@interface ASDisplayNode (Beta)
+ (BOOL)shouldUseNewRenderingRange;
+ (void)setShouldUseNewRenderingRange:(BOOL)shouldUseNewRenderingRange;
+ (BOOL)usesImplicitHierarchyManagement;
+ (void)setUsesImplicitHierarchyManagement:(BOOL)enabled;

View File

@ -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) {

View File

@ -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;

View File

@ -19,9 +19,6 @@ NS_ASSUME_NONNULL_BEGIN
@end
@interface ASCollectionViewLayoutControllerStable : ASCollectionViewLayoutController
@end
@interface ASCollectionViewLayoutControllerBeta : ASCollectionViewLayoutController
@end

View File

@ -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

View File

@ -77,9 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
@end
@interface ASRangeControllerStable : ASRangeController
@end
@interface ASRangeControllerBeta : ASRangeController
@end

View File

@ -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

View File

@ -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];
}
}

View File

@ -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];
}
}
}

View File

@ -14,7 +14,6 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[ASDisplayNode setShouldUseNewRenderingRange:YES];
return YES;
}