diff --git a/AsyncDisplayKit/ASDisplayNode+Subclasses.h b/AsyncDisplayKit/ASDisplayNode+Subclasses.h index f8602a39bd..16a1ea7b32 100644 --- a/AsyncDisplayKit/ASDisplayNode+Subclasses.h +++ b/AsyncDisplayKit/ASDisplayNode+Subclasses.h @@ -63,7 +63,7 @@ /** * @abstract Whether the view or layer of this display node is currently in a window */ -@property (nonatomic, readonly, assign, getter=isInWindow) BOOL inWindow; +@property (nonatomic, readonly, assign, getter=isInHierarchy) BOOL inHierarchy; /** @name View Lifecycle */ diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 8e056e7168..5ec6221d7a 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -109,7 +109,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()) _displaySentinel = [[ASSentinel alloc] init]; - _flags.isInWindow = NO; + _flags.isInHierarchy = NO; _flags.displaysAsynchronously = YES; // As an optimization, it may be worth a caching system that performs these checks once per class in +initialize (see above). @@ -660,7 +660,7 @@ static bool disableNotificationsForMovingBetweenParents(ASDisplayNode *from, ASD if (!from || !to) return NO; if (from->_flags.synchronous) return NO; if (to->_flags.synchronous) return NO; - if (from->_flags.isInWindow != to->_flags.isInWindow) return NO; + if (from->_flags.isInHierarchy != to->_flags.isInHierarchy) return NO; return YES; } @@ -1021,8 +1021,8 @@ static NSInteger incrementIfFound(NSInteger i) { { ASDisplayNodeAssertMainThread(); ASDisplayNodeAssert(!_flags.isEnteringHierarchy, @"Should not cause recursive __enterHierarchy"); - if (!self.inWindow && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) { - self.inWindow = YES; + if (!self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) { + self.inHierarchy = YES; _flags.isEnteringHierarchy = YES; if (self.shouldRasterizeDescendants) { // Nodes that are descendants of a rasterized container do not have views or layers, and so cannot receive visibility notifications directly via orderIn/orderOut CALayer actions. Manually send visibility notifications to rasterized descendants. @@ -1043,8 +1043,8 @@ static NSInteger incrementIfFound(NSInteger i) { { ASDisplayNodeAssertMainThread(); ASDisplayNodeAssert(!_flags.isExitingHierarchy, @"Should not cause recursive __exitHierarchy"); - if (self.inWindow && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) { - self.inWindow = NO; + if (self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __hasParentWithVisibilityNotificationsDisabled]) { + self.inHierarchy = NO; [self.asyncLayer cancelAsyncDisplay]; @@ -1417,20 +1417,20 @@ static void _recursiveSetPreventOrCancelDisplay(ASDisplayNode *node, CALayer *la self.asyncLayer.displaySuspended = flag; } -- (BOOL)isInWindow +- (BOOL)isInHierarchy { ASDisplayNodeAssertThreadAffinity(self); ASDN::MutexLocker l(_propertyLock); - return _flags.isInWindow; + return _flags.isInHierarchy; } -- (void)setInWindow:(BOOL)inWindow +- (void)setInHierarchy:(BOOL)inHierarchy { ASDisplayNodeAssertThreadAffinity(self); ASDN::MutexLocker l(_propertyLock); - _flags.isInWindow = inWindow; + _flags.isInHierarchy = inHierarchy; } + (dispatch_queue_t)asyncSizingQueue diff --git a/AsyncDisplayKit/Details/_ASDisplayView.mm b/AsyncDisplayKit/Details/_ASDisplayView.mm index 86f1f8e8fa..a2470d2353 100644 --- a/AsyncDisplayKit/Details/_ASDisplayView.mm +++ b/AsyncDisplayKit/Details/_ASDisplayView.mm @@ -80,9 +80,9 @@ - (void)willMoveToWindow:(UIWindow *)newWindow { BOOL visible = newWindow != nil; - if (visible && !_node.inWindow) { + if (visible && !_node.inHierarchy) { [_node __enterHierarchy]; - } else if (!visible && _node.inWindow) { + } else if (!visible && _node.inHierarchy) { [_node __exitHierarchy]; } } diff --git a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h index 657361b926..821fb2f175 100644 --- a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h +++ b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h @@ -72,7 +72,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()); unsigned isMeasured:1; unsigned isEnteringHierarchy:1; unsigned isExitingHierarchy:1; - unsigned isInWindow:1; + unsigned isInHierarchy:1; unsigned visibilityNotificationsDisabled:VISIBILITY_NOTIFICATIONS_DISABLED_BITS; } _flags; @@ -102,17 +102,17 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()); - (void)__layout; - (void)__setSupernode:(ASDisplayNode *)supernode; -// The visibility state of the node. Changed before calling willAppear, willDisappear, and didDisappear. -@property (nonatomic, readwrite, assign, getter = isInWindow) BOOL inWindow; +// Changed before calling willEnterHierarchy / didExitHierarchy. +@property (nonatomic, readwrite, assign, getter = isInHierarchy) BOOL inHierarchy; // Private API for helper functions / unit tests. Use ASDisplayNodeDisableHierarchyNotifications() to control this. - (BOOL)__visibilityNotificationsDisabled; - (void)__incrementVisibilityNotificationsDisabled; - (void)__decrementVisibilityNotificationsDisabled; -// Call willEnterHierarchy if necessary and set inWindow = YES if visibility notifications are enabled on all of its parents +// Call willEnterHierarchy if necessary and set inHierarchy = YES if visibility notifications are enabled on all of its parents - (void)__enterHierarchy; -// Call didExitHierarchy if necessary and set inWindow = NO if visibility notifications are enabled on all of its parents +// Call didExitHierarchy if necessary and set inHierarchy = NO if visibility notifications are enabled on all of its parents - (void)__exitHierarchy; // Returns the ancestor node that rasterizes descendants, or nil if none. diff --git a/AsyncDisplayKitTests/ASDisplayNodeAppearanceTests.m b/AsyncDisplayKitTests/ASDisplayNodeAppearanceTests.m index 118b274088..78e2fdb978 100644 --- a/AsyncDisplayKitTests/ASDisplayNodeAppearanceTests.m +++ b/AsyncDisplayKitTests/ASDisplayNodeAppearanceTests.m @@ -139,7 +139,7 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C XCTAssertEqual([_willEnterHierarchyCounts countForObject:n], 1u, @"willEnterHierarchy not called when node's view added to hierarchy"); XCTAssertEqual([_didExitHierarchyCounts countForObject:n], 0u, @"didExitHierarchy erroneously called"); - XCTAssertTrue(n.inWindow, @"Node should be visible"); + XCTAssertTrue(n.inHierarchy, @"Node should be visible"); if (isLayerBacked) { [n.layer removeFromSuperlayer]; @@ -147,7 +147,7 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C [n.view removeFromSuperview]; } - XCTAssertFalse(n.inWindow, @"Node should be not visible"); + XCTAssertFalse(n.inHierarchy, @"Node should be not visible"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:n], 1u, @"willEnterHierarchy not called when node's view added to hierarchy"); XCTAssertEqual([_didExitHierarchyCounts countForObject:n], 1u, @"didExitHierarchy erroneously called"); @@ -175,11 +175,11 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C [parent addSubnode:a]; - XCTAssertFalse(parent.inWindow, @"Nothing should be visible"); - XCTAssertFalse(a.inWindow, @"Nothing should be visible"); - XCTAssertFalse(b.inWindow, @"Nothing should be visible"); - XCTAssertFalse(aa.inWindow, @"Nothing should be visible"); - XCTAssertFalse(ab.inWindow, @"Nothing should be visible"); + XCTAssertFalse(parent.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(a.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(b.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(aa.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(ab.inHierarchy, @"Nothing should be visible"); if (isLayerBacked) { [window.layer addSublayer:parent.layer]; @@ -193,22 +193,22 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C XCTAssertEqual([_willEnterHierarchyCounts countForObject:aa], 0u, @"Should not have appeared yet"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:ab], 0u, @"Should not have appeared yet"); - XCTAssertTrue(parent.inWindow, @"Should be visible"); - XCTAssertTrue(a.inWindow, @"Should be visible"); - XCTAssertFalse(b.inWindow, @"Nothing should be visible"); - XCTAssertFalse(aa.inWindow, @"Nothing should be visible"); - XCTAssertFalse(ab.inWindow, @"Nothing should be visible"); + XCTAssertTrue(parent.inHierarchy, @"Should be visible"); + XCTAssertTrue(a.inHierarchy, @"Should be visible"); + XCTAssertFalse(b.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(aa.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(ab.inHierarchy, @"Nothing should be visible"); // Add to an already-visible node should make the node visible [parent addSubnode:b]; [a insertSubnode:aa atIndex:0]; [a insertSubnode:ab aboveSubnode:aa]; - XCTAssertTrue(parent.inWindow, @"Should be visible"); - XCTAssertTrue(a.inWindow, @"Should be visible"); - XCTAssertTrue(b.inWindow, @"Should be visible after adding to visible parent"); - XCTAssertTrue(aa.inWindow, @"Nothing should be visible"); - XCTAssertTrue(ab.inWindow, @"Nothing should be visible"); + XCTAssertTrue(parent.inHierarchy, @"Should be visible"); + XCTAssertTrue(a.inHierarchy, @"Should be visible"); + XCTAssertTrue(b.inHierarchy, @"Should be visible after adding to visible parent"); + XCTAssertTrue(aa.inHierarchy, @"Nothing should be visible"); + XCTAssertTrue(ab.inHierarchy, @"Nothing should be visible"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:parent], 1u, @"Should have -willEnterHierarchy called once"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:a], 1u, @"Should have -willEnterHierarchy called once"); @@ -222,11 +222,11 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C [parent.view removeFromSuperview]; } - XCTAssertFalse(parent.inWindow, @"Nothing should be visible"); - XCTAssertFalse(a.inWindow, @"Nothing should be visible"); - XCTAssertFalse(b.inWindow, @"Nothing should be visible"); - XCTAssertFalse(aa.inWindow, @"Nothing should be visible"); - XCTAssertFalse(ab.inWindow, @"Nothing should be visible"); + XCTAssertFalse(parent.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(a.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(b.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(aa.inHierarchy, @"Nothing should be visible"); + XCTAssertFalse(ab.inHierarchy, @"Nothing should be visible"); } - (void)testAppearanceMethodsNoLayer @@ -262,36 +262,36 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C [parentSynchronousNode addSubnode:layerBackedNode]; [parentSynchronousNode addSubnode:viewBackedNode]; - XCTAssertFalse(parentSynchronousNode.inWindow, @"Should not yet be visible"); - XCTAssertFalse(layerBackedNode.inWindow, @"Should not yet be visible"); - XCTAssertFalse(viewBackedNode.inWindow, @"Should not yet be visible"); + XCTAssertFalse(parentSynchronousNode.inHierarchy, @"Should not yet be visible"); + XCTAssertFalse(layerBackedNode.inHierarchy, @"Should not yet be visible"); + XCTAssertFalse(viewBackedNode.inHierarchy, @"Should not yet be visible"); [window addSubview:parentSynchronousNode.view]; // This is a known case that isn't supported - XCTAssertFalse(parentSynchronousNode.inWindow, @"Synchronous views are not currently marked visible"); + XCTAssertFalse(parentSynchronousNode.inHierarchy, @"Synchronous views are not currently marked visible"); - XCTAssertTrue(layerBackedNode.inWindow, @"Synchronous views' subviews should get marked visible"); - XCTAssertTrue(viewBackedNode.inWindow, @"Synchronous views' subviews should get marked visible"); + XCTAssertTrue(layerBackedNode.inHierarchy, @"Synchronous views' subviews should get marked visible"); + XCTAssertTrue(viewBackedNode.inHierarchy, @"Synchronous views' subviews should get marked visible"); // Try moving a node to/from a synchronous node in the window with the node API // Setup [layerBackedNode removeFromSupernode]; [viewBackedNode removeFromSupernode]; - XCTAssertFalse(layerBackedNode.inWindow, @"aoeu"); - XCTAssertFalse(viewBackedNode.inWindow, @"aoeu"); + XCTAssertFalse(layerBackedNode.inHierarchy, @"aoeu"); + XCTAssertFalse(viewBackedNode.inHierarchy, @"aoeu"); // now move to synchronous node [parentSynchronousNode addSubnode:layerBackedNode]; [parentSynchronousNode insertSubnode:viewBackedNode aboveSubnode:layerBackedNode]; - XCTAssertTrue(layerBackedNode.inWindow, @"Synchronous views' subviews should get marked visible"); - XCTAssertTrue(viewBackedNode.inWindow, @"Synchronous views' subviews should get marked visible"); + XCTAssertTrue(layerBackedNode.inHierarchy, @"Synchronous views' subviews should get marked visible"); + XCTAssertTrue(viewBackedNode.inHierarchy, @"Synchronous views' subviews should get marked visible"); [parentSynchronousNode.view removeFromSuperview]; - XCTAssertFalse(parentSynchronousNode.inWindow, @"Should not have changed"); - XCTAssertFalse(layerBackedNode.inWindow, @"Should have been marked invisible when synchronous superview was removed from the window"); - XCTAssertFalse(viewBackedNode.inWindow, @"Should have been marked invisible when synchronous superview was removed from the window"); + XCTAssertFalse(parentSynchronousNode.inHierarchy, @"Should not have changed"); + XCTAssertFalse(layerBackedNode.inHierarchy, @"Should have been marked invisible when synchronous superview was removed from the window"); + XCTAssertFalse(viewBackedNode.inHierarchy, @"Should have been marked invisible when synchronous superview was removed from the window"); [window release]; [parentSynchronousNode release]; @@ -315,11 +315,11 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C [parentA addSubnode:child]; [child addSubnode:childSubnode]; - XCTAssertFalse(parentA.inWindow, @"Should not yet be visible"); - XCTAssertFalse(parentB.inWindow, @"Should not yet be visible"); - XCTAssertFalse(child.inWindow, @"Should not yet be visible"); - XCTAssertFalse(childSubnode.inWindow, @"Should not yet be visible"); - XCTAssertFalse(childSubnode.inWindow, @"Should not yet be visible"); + XCTAssertFalse(parentA.inHierarchy, @"Should not yet be visible"); + XCTAssertFalse(parentB.inHierarchy, @"Should not yet be visible"); + XCTAssertFalse(child.inHierarchy, @"Should not yet be visible"); + XCTAssertFalse(childSubnode.inHierarchy, @"Should not yet be visible"); + XCTAssertFalse(childSubnode.inHierarchy, @"Should not yet be visible"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:child], 0u, @"Should not have -willEnterHierarchy called"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:childSubnode], 0u, @"Should not have -willEnterHierarchy called"); @@ -332,10 +332,10 @@ static dispatch_block_t modifyMethodByAddingPrologueBlockAndReturnCleanupBlock(C [window addSubview:parentB.view]; } - XCTAssertTrue(parentA.inWindow, @"Should be visible after added to window"); - XCTAssertTrue(parentB.inWindow, @"Should be visible after added to window"); - XCTAssertTrue(child.inWindow, @"Should be visible after parent added to window"); - XCTAssertTrue(childSubnode.inWindow, @"Should be visible after parent added to window"); + XCTAssertTrue(parentA.inHierarchy, @"Should be visible after added to window"); + XCTAssertTrue(parentB.inHierarchy, @"Should be visible after added to window"); + XCTAssertTrue(child.inHierarchy, @"Should be visible after parent added to window"); + XCTAssertTrue(childSubnode.inHierarchy, @"Should be visible after parent added to window"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:child], 1u, @"Should have -willEnterHierarchy called once"); XCTAssertEqual([_willEnterHierarchyCounts countForObject:childSubnode], 1u, @"Should have -willEnterHierarchy called once");