Only require node sizes once per run loop, and only if a node's size has changed

This commit is contained in:
Adlai Holler
2015-11-30 17:20:32 -08:00
parent 9032962353
commit 04d93532bc
4 changed files with 44 additions and 8 deletions

View File

@@ -15,12 +15,13 @@ typedef NSUInteger ASCellNodeAnimation;
@protocol ASCellNodeLayoutDelegate <NSObject>
/**
* Notifies the delegate that the specified cell node has done a relayout.
* Notifies the delegate that the specified cell node has done a relayout
* that resulted in a change of `calculatedSize`.
* The notification is done on main thread.
*
* @param node A node informing the delegate about the relayout.
*/
- (void)nodeDidRelayout:(ASCellNode *)node;
- (void)nodeDidRelayoutWithSizeChange:(ASCellNode *)node;
@end
/**

View File

@@ -53,11 +53,12 @@
- (void)setNeedsLayout
{
ASDisplayNodeAssertThreadAffinity(self);
CGSize oldSize = self.calculatedSize;
[super setNeedsLayout];
if (_layoutDelegate != nil) {
if (_layoutDelegate != nil && !CGSizeEqualToSize(oldSize, self.calculatedSize)) {
ASPerformBlockOnMainThread(^{
[_layoutDelegate nodeDidRelayout:self];
[_layoutDelegate nodeDidRelayoutWithSizeChange:self];
});
}
}

View File

@@ -155,6 +155,7 @@ static BOOL _isInterceptedSelector(SEL sel)
BOOL _asyncDelegateImplementsInsetSection;
BOOL _collectionViewLayoutImplementsInsetSection;
BOOL _asyncDataSourceImplementsConstrainedSizeForNode;
BOOL _queuedNodeSizeUpdate;
ASBatchContext *_batchContext;
@@ -912,10 +913,26 @@ static BOOL _isInterceptedSelector(SEL sel)
#pragma mark - ASCellNodeDelegate
- (void)nodeDidRelayout:(ASCellNode *)node
- (void)nodeDidRelayoutWithSizeChange:(ASCellNode *)node
{
ASDisplayNodeAssertMainThread();
// Cause UICollectionView to requery for the new height of this node
if (_queuedNodeSizeUpdate) {
return;
}
_queuedNodeSizeUpdate = YES;
[self performSelector:@selector(requeryNodeSizes)
withObject:nil
afterDelay:0
inModes:@[ NSRunLoopCommonModes ]];
}
// Cause UICollectionView to requery for the new size of all nodes
- (void)requeryNodeSizes
{
_queuedNodeSizeUpdate = NO;
[super performBatchUpdates:^{} completion:nil];
}

View File

@@ -179,6 +179,7 @@ static BOOL _isInterceptedSelector(SEL sel)
CGFloat _nodesConstrainedWidth;
BOOL _ignoreNodesConstrainedWidthChange;
BOOL _queuedNodeHeightUpdate;
}
@property (atomic, assign) BOOL asyncDataSourceLocked;
@@ -909,10 +910,26 @@ static BOOL _isInterceptedSelector(SEL sel)
#pragma mark - ASCellNodeLayoutDelegate
- (void)nodeDidRelayout:(ASCellNode *)node
- (void)nodeDidRelayoutWithSizeChange:(ASCellNode *)node
{
ASDisplayNodeAssertMainThread();
// Cause UITableView to requery for the new height of this node
if (_queuedNodeHeightUpdate) {
return;
}
_queuedNodeHeightUpdate = YES;
[self performSelector:@selector(requeryNodeHeights)
withObject:nil
afterDelay:0
inModes:@[ NSRunLoopCommonModes ]];
}
// Cause UITableView to requery for the new height of this node
- (void)requeryNodeHeights
{
_queuedNodeHeightUpdate = NO;
[super beginUpdates];
[super endUpdates];
}