diff --git a/AsyncDisplayKit/Details/ASRangeController.mm b/AsyncDisplayKit/Details/ASRangeController.mm index a79e27f67e..482eea65fb 100644 --- a/AsyncDisplayKit/Details/ASRangeController.mm +++ b/AsyncDisplayKit/Details/ASRangeController.mm @@ -145,8 +145,6 @@ - (BOOL)shouldSkipVisibleNodesForRangeType:(ASLayoutRangeType)rangeType - (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)cellNode { - [cellNode recursivelySetDisplaySuspended:NO]; - if (cellNode.view.superview == contentView) { // this content view is already correctly configured return; diff --git a/AsyncDisplayKit/Details/ASRangeHandlerRender.mm b/AsyncDisplayKit/Details/ASRangeHandlerRender.mm index 075535fc26..ac83bcda3c 100644 --- a/AsyncDisplayKit/Details/ASRangeHandlerRender.mm +++ b/AsyncDisplayKit/Details/ASRangeHandlerRender.mm @@ -12,64 +12,34 @@ #import "ASDisplayNode+Subclasses.h" #import "ASDisplayNodeInternal.h" -@interface ASDisplayNode (ASRangeHandlerRender) - -- (void)display; -- (void)recursivelyDisplay; - -@end - -@implementation ASDisplayNode (ASRangeHandlerRender) +@implementation ASRangeHandlerRender -- (void)display ++ (UIWindow *)workingWindow { - if (![self __shouldLoadViewOrLayer]) { - return; - } - ASDisplayNodeAssertMainThread(); - ASDisplayNodeAssert(self.nodeLoaded, @"backing store must be loaded before calling -display"); - - CALayer *layer = self.layer; - - // rendering a backing store requires a node be laid out - [layer setNeedsLayout]; - [layer layoutIfNeeded]; - - if (layer.contents) { - return; - } - - [layer setNeedsDisplay]; - [layer displayIfNeeded]; + + // 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; } -- (void)recursivelyDisplay -{ - if (![self __shouldLoadViewOrLayer]) { - return; - } - - for (ASDisplayNode *node in self.subnodes) { - [node recursivelyDisplay]; - } - - [self display]; -} - -@end - -@implementation ASRangeHandlerRender - - (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType { ASDisplayNodeAssertMainThread(); ASDisplayNodeAssert(rangeType == ASLayoutRangeTypeRender, @"Render delegate should not handle other ranges"); - // if node is in the working range it should not actively be in view - [node.view removeFromSuperview]; + [node recursivelySetDisplaySuspended:NO]; - [node recursivelyDisplay]; + // add the node to an off-screen window to force display and preserve its contents + [[self.class workingWindow] addSubnode:node]; } - (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType