Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 33 additions & 14 deletions AsyncDisplayKit/Details/ASRangeHandlerRender.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,44 @@
#import "ASDisplayNode.h"
#import "ASDisplayNode+Subclasses.h"
#import "ASDisplayNodeInternal.h"
#import "_ASDisplayView.h"

@interface ASRangeHandlerRender ()
@property (nonatomic,readonly) UIWindow *workingWindow;
@end

@implementation ASRangeHandlerRender

+ (UIWindow *)workingWindow
@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
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.hidden = YES;
workingWindow.alpha = 0.0;
});
return workingWindow;

if (!_workingWindow) {
_workingWindow = [[UIWindow alloc] initWithFrame:CGRectZero];
_workingWindow.windowLevel = UIWindowLevelNormal - 1000;
_workingWindow.userInteractionEnabled = NO;
_workingWindow.hidden = YES;
_workingWindow.alpha = 0.0;
}

return _workingWindow;
}

- (void)dealloc
{
NSArray *views = [self.workingWindow.subviews copy];
for(_ASDisplayView *view in views) {
if (![view isKindOfClass:[_ASDisplayView class]]) {
continue;
}
ASDisplayNode *node = view.asyncdisplaykit_node;
[self node:node exitedRangeOfType:ASLayoutRangeTypeRender];
}
}

- (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType
Expand All @@ -44,7 +63,7 @@ - (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeTy
// 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 class] workingWindow] layer] addSublayer:node.layer];
[[[self workingWindow] layer] addSublayer:node.layer];
}

- (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType
Expand All @@ -71,7 +90,7 @@ - (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeTyp

[node recursivelySetDisplaySuspended:YES];

if (node.layer.superlayer != [[[self class] workingWindow] layer]) {
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).
Expand Down