Merge pull request #898 from Adlai-Holler/OptimizeNodeDidRelayout

Reduce Frequency of beginUpdates/endUpdates Due to Node Relayout
This commit is contained in:
appleguy 2015-12-03 21:02:22 -08:00
commit 3a04cb7cc8
4 changed files with 44 additions and 7 deletions

View File

@ -19,8 +19,9 @@ typedef NSUInteger ASCellNodeAnimation;
* The notification is done on main thread. * The notification is done on main thread.
* *
* @param node A node informing the delegate about the relayout. * @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; - (void)nodeDidRelayout:(ASCellNode *)node sizeChanged:(BOOL)sizeChanged;
@end @end
/** /**

View File

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

View File

@ -156,6 +156,7 @@ static BOOL _isInterceptedSelector(SEL sel)
BOOL _asyncDelegateImplementsInsetSection; BOOL _asyncDelegateImplementsInsetSection;
BOOL _collectionViewLayoutImplementsInsetSection; BOOL _collectionViewLayoutImplementsInsetSection;
BOOL _asyncDataSourceImplementsConstrainedSizeForNode; BOOL _asyncDataSourceImplementsConstrainedSizeForNode;
BOOL _queuedNodeSizeUpdate;
ASBatchContext *_batchContext; ASBatchContext *_batchContext;
@ -911,10 +912,26 @@ static BOOL _isInterceptedSelector(SEL sel)
#pragma mark - ASCellNodeDelegate #pragma mark - ASCellNodeDelegate
- (void)nodeDidRelayout:(ASCellNode *)node - (void)nodeDidRelayout:(ASCellNode *)node sizeChanged:(BOOL)sizeChanged
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
// Cause UICollectionView to requery for the new height of this node
if (!sizeChanged || _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]; [super performBatchUpdates:^{} completion:nil];
} }

View File

@ -181,6 +181,7 @@ static BOOL _isInterceptedSelector(SEL sel)
CGFloat _nodesConstrainedWidth; CGFloat _nodesConstrainedWidth;
BOOL _ignoreNodesConstrainedWidthChange; BOOL _ignoreNodesConstrainedWidthChange;
BOOL _queuedNodeHeightUpdate;
} }
@property (atomic, assign) BOOL asyncDataSourceLocked; @property (atomic, assign) BOOL asyncDataSourceLocked;
@ -908,10 +909,26 @@ static BOOL _isInterceptedSelector(SEL sel)
#pragma mark - ASCellNodeLayoutDelegate #pragma mark - ASCellNodeLayoutDelegate
- (void)nodeDidRelayout:(ASCellNode *)node - (void)nodeDidRelayout:(ASCellNode *)node sizeChanged:(BOOL)sizeChanged
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (!sizeChanged || _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 // Cause UITableView to requery for the new height of this node
- (void)requeryNodeHeights
{
_queuedNodeHeightUpdate = NO;
[super beginUpdates]; [super beginUpdates];
[super endUpdates]; [super endUpdates];
} }