Manually display nodes

Added a sample project that will demonstrate how to manually display nodes. Removed the UIWindow hack that coupled display of nodes with Core Animation transactions.
This commit is contained in:
Ryan Nystrom
2014-11-25 13:33:40 -08:00
parent ab46377af2
commit 8b0dbf7288
32 changed files with 1240 additions and 24 deletions

View File

@@ -91,22 +91,6 @@
return sizingQueue;
}
+ (UIView *)workingView
{
// we add nodes' views to this invisible window to start async rendering
static UIWindow *workingWindow = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
workingWindow = [[UIWindow alloc] initWithFrame:CGRectZero];
workingWindow.windowLevel = UIWindowLevelNormal - 1000;
workingWindow.userInteractionEnabled = NO;
workingWindow.clipsToBounds = YES;
workingWindow.hidden = YES;
});
return workingWindow;
}
#pragma mark -
#pragma mark Helpers.
@@ -191,7 +175,7 @@ static BOOL ASRangeIsValid(NSRange range)
NSInteger index = [self indexForIndexPath:node.asyncdisplaykit_indexPath];
if (NSLocationInRange(index, _workingRange)) {
// move the node's view to the working range area, so its rendering persists
[self moveNodeToWorkingView:node];
[self moveNodeToWorkingRange:node];
} else {
// this node isn't in the working range, remove it from the view hierarchy
[self removeNodeFromWorkingView:node];
@@ -205,20 +189,22 @@ static BOOL ASRangeIsValid(NSRange range)
[node recursiveSetPreventOrCancelDisplay:YES];
[node.view removeFromSuperview];
// 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.
[node recursivelyReclaimMemory];
[_workingIndexPaths removeObject:node.asyncdisplaykit_indexPath];
}
- (void)moveNodeToWorkingView:(ASCellNode *)node
- (void)moveNodeToWorkingRange:(ASCellNode *)node
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert(node, @"invalid argument");
[self moveNode:node toView:[ASRangeController workingView]];
// if node is in the working range it should not actively be in view
[node.view removeFromSuperview];
[_workingIndexPaths addObject:node.asyncdisplaykit_indexPath];
}
@@ -231,7 +217,7 @@ static BOOL ASRangeIsValid(NSRange range)
[CATransaction begin];
[view addSubview:node.view];
[CATransaction commit];
}
@@ -481,7 +467,7 @@ static NSRange ASCalculateWorkingRange(ASRangeTuningParameters params, ASScrollD
_nodeSizes,
[_delegate rangeControllerViewportSize:self]);
}
[self setWorkingRange:workingRange];
}
@@ -513,7 +499,7 @@ static NSRange ASCalculateWorkingRange(ASRangeTuningParameters params, ASScrollD
// if a node in the working range is still sizing, the sizing logic will add it to the working range for us later
ASCellNode *node = [self sizedNodeForIndexPath:indexPath];
if (node) {
[self moveNodeToWorkingView:node];
[self moveNodeToWorkingRange:node];
} else {
ASDisplayNodeAssert(_sizedNodeCount != _totalNodeCount, @"logic error");
}
@@ -577,6 +563,8 @@ static NSRange ASCalculateWorkingRange(ASRangeTuningParameters params, ASScrollD
for (NSIndexPath *indexPath in indexPaths) {
ASCellNode *node = _nodes[indexPath];
_nodeSizes[[self indexForIndexPath:indexPath]] = [NSValue valueWithCGSize:node.calculatedSize];
[node display];
}
ASDisplayNodeAssert(_nodeSizes.count == _sizedNodeCount, @"logic error");