diff --git a/AsyncDisplayKit/ASCellNode+Internal.h b/AsyncDisplayKit/ASCellNode+Internal.h index a660e46d80..8dba99cded 100644 --- a/AsyncDisplayKit/ASCellNode+Internal.h +++ b/AsyncDisplayKit/ASCellNode+Internal.h @@ -8,6 +8,28 @@ #import "ASCellNode.h" -@interface ASCellNode (Internal) +@protocol ASCellNodeLayoutDelegate + +/** + * Notifies the delegate that the specified cell node has done a relayout. + * The notification is done on main thread. + * + * This will not be called due to measurement passes before the node has loaded + * its view, even if triggered by -setNeedsLayout, as it is assumed these are + * not relevant to UIKit. Indeed, these calls can cause consistency issues. + * + * @param node A node informing the delegate about the relayout. + * @param sizeChanged `YES` if the node's `calculatedSize` changed during the relayout, `NO` otherwise. + */ +- (void)nodeDidRelayout:(ASCellNode *)node sizeChanged:(BOOL)sizeChanged; + +@end + +@interface ASCellNode () + +/* + * A delegate to be notified (on main thread) after a relayout. + */ +@property (nonatomic, weak) id layoutDelegate; @end diff --git a/AsyncDisplayKit/ASCellNode.h b/AsyncDisplayKit/ASCellNode.h index 8788d30015..5460627a0a 100644 --- a/AsyncDisplayKit/ASCellNode.h +++ b/AsyncDisplayKit/ASCellNode.h @@ -14,19 +14,6 @@ NS_ASSUME_NONNULL_BEGIN typedef NSUInteger ASCellNodeAnimation; -@protocol ASCellNodeLayoutDelegate - -/** - * Notifies the delegate that the specified cell node has done a relayout. - * The notification is done on main thread. - * - * @param node A node informing the delegate about the relayout. - * @param sizeChanged `YES` if the node's `calculatedSize` changed during the relayout, `NO` otherwise. - */ -- (void)nodeDidRelayout:(ASCellNode *)node sizeChanged:(BOOL)sizeChanged; - -@end - /** * Generic cell node. Subclass this instead of `ASDisplayNode` to use with `ASTableView` and `ASCollectionView`. */ @@ -71,11 +58,6 @@ typedef NSUInteger ASCellNodeAnimation; */ @property (nonatomic, assign) BOOL highlighted; -/* - * A delegate to be notified (on main thread) after a relayout. - */ -@property (nonatomic, weak) id layoutDelegate; - /* * ASCellNode must forward touch events in order for UITableView and UICollectionView tap handling to work. Overriding * these methods (e.g. for highlighting) requires the super method be called. diff --git a/AsyncDisplayKit/ASCellNode.m b/AsyncDisplayKit/ASCellNode.m index 3e1fccdbc8..b594cfcce2 100644 --- a/AsyncDisplayKit/ASCellNode.m +++ b/AsyncDisplayKit/ASCellNode.m @@ -6,7 +6,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import "ASCellNode.h" +#import "ASCellNode+Internal.h" #import "ASInternalHelpers.h" #import @@ -27,6 +27,7 @@ @end @implementation ASCellNode +@synthesize layoutDelegate = _layoutDelegate; - (instancetype)init { @@ -97,7 +98,7 @@ CGSize oldSize = self.calculatedSize; [super setNeedsLayout]; - if (_layoutDelegate != nil) { + if (_layoutDelegate != nil && self.isNodeLoaded) { BOOL sizeChanged = !CGSizeEqualToSize(oldSize, self.calculatedSize); ASPerformBlockOnMainThread(^{ [_layoutDelegate nodeDidRelayout:self sizeChanged:sizeChanged]; diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 0aec6ef564..636db362a2 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -1882,7 +1882,6 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) - (ASSizeRange)constrainedSizeForCalculatedLayout { - ASDisplayNodeAssertThreadAffinity(self); return _constrainedSize; } diff --git a/AsyncDisplayKit/ASTableView.mm b/AsyncDisplayKit/ASTableView.mm index 923e690236..c6eefd394b 100644 --- a/AsyncDisplayKit/ASTableView.mm +++ b/AsyncDisplayKit/ASTableView.mm @@ -10,6 +10,7 @@ #import "ASAssert.h" #import "ASBatchFetching.h" +#import "ASCellNode+Internal.h" #import "ASChangeSetDataController.h" #import "ASDelegateProxy.h" #import "ASDisplayNode+Beta.h"