mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-05 04:10:16 +00:00
Add support for loaded node layout for supplementary views
This commit is contained in:
parent
952a66a924
commit
ee0cc2001a
@ -735,7 +735,6 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
{
|
||||
ASCellNode *node = [_asyncDataSource collectionView:self nodeForSupplementaryElementOfKind:kind atIndexPath:indexPath];
|
||||
ASDisplayNodeAssert(node != nil, @"A node must be returned for a supplementary node");
|
||||
ASDisplayNodeAssert(!node.nodeLoaded, @"The supplementary node must not be loaded");
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,9 @@
|
||||
[self _populateSupplementaryNodesOfKind:kind withMutableNodes:nodes mutableIndexPaths:indexPaths];
|
||||
_pendingNodes[kind] = nodes;
|
||||
_pendingIndexPaths[kind] = indexPaths;
|
||||
|
||||
// Measure loaded nodes before leaving the main thread
|
||||
[self layoutLoadedNodes:nodes ofKind:kind atIndexPaths:indexPaths];
|
||||
}];
|
||||
}
|
||||
|
||||
@ -66,8 +69,8 @@
|
||||
[self batchLayoutNodes:nodes ofKind:kind atIndexPaths:_pendingIndexPaths[kind] completion:^(NSArray *nodes, NSArray *indexPaths) {
|
||||
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
}];
|
||||
_pendingNodes[kind] = nil;
|
||||
_pendingIndexPaths[kind] = nil;
|
||||
[_pendingNodes removeObjectForKey:kind];
|
||||
[_pendingIndexPaths removeObjectForKey:kind];
|
||||
}];
|
||||
}
|
||||
|
||||
@ -81,6 +84,9 @@
|
||||
[self _populateSupplementaryNodesOfKind:kind withSections:sections mutableNodes:nodes mutableIndexPaths:indexPaths];
|
||||
_pendingNodes[kind] = nodes;
|
||||
_pendingIndexPaths[kind] = indexPaths;
|
||||
|
||||
// Measure loaded nodes before leaving the main thread
|
||||
[self layoutLoadedNodes:nodes ofKind:kind atIndexPaths:indexPaths];
|
||||
}];
|
||||
}
|
||||
|
||||
@ -119,6 +125,9 @@
|
||||
[self _populateSupplementaryNodesOfKind:kind withSections:sections mutableNodes:nodes mutableIndexPaths:indexPaths];
|
||||
_pendingNodes[kind] = nodes;
|
||||
_pendingIndexPaths[kind] = indexPaths;
|
||||
|
||||
// Measure loaded nodes before leaving the main thread
|
||||
[self layoutLoadedNodes:nodes ofKind:kind atIndexPaths:indexPaths];
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,14 @@
|
||||
*/
|
||||
- (void)batchLayoutNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths completion:(void (^)(NSArray *nodes, NSArray *indexPaths))completionBlock;
|
||||
|
||||
/*
|
||||
* Perform measurement and layout of loaded nodes on the main thread, skipping unloaded nodes.
|
||||
*
|
||||
* @discussion Once nodes have loaded their views, we can't layout in the background so this is a chance
|
||||
* to do so immediately on the main thread.
|
||||
*/
|
||||
- (void)layoutLoadedNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths;
|
||||
|
||||
/**
|
||||
* Provides the size range for a specific node during the layout process.
|
||||
*/
|
||||
|
@ -103,30 +103,6 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
|
||||
#pragma mark - Cell Layout
|
||||
|
||||
- (void)_layoutNode:(ASCellNode *)node withConstrainedSize:(ASSizeRange)constrainedSize
|
||||
{
|
||||
[node measureWithSizeRange:constrainedSize];
|
||||
node.frame = CGRectMake(0.0f, 0.0f, node.calculatedSize.width, node.calculatedSize.height);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform measurement and layout of loaded nodes on the main thread, skipping unloaded nodes.
|
||||
*
|
||||
* @discussion Once nodes have loaded their views, we can't layout in the background so this is a chance
|
||||
* to do so immediately on the main thread.
|
||||
*/
|
||||
- (void)_layoutNodesWithMainThreadAffinity:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths {
|
||||
NSAssert(NSThread.isMainThread, @"Main thread layout must be on the main thread.");
|
||||
|
||||
[indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, __unused BOOL * stop) {
|
||||
ASCellNode *node = nodes[idx];
|
||||
if (node.isNodeLoaded) {
|
||||
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath];
|
||||
[self _layoutNode:node withConstrainedSize:constrainedSize];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)batchLayoutNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths completion:(void (^)(NSArray *nodes, NSArray *indexPaths))completionBlock
|
||||
{
|
||||
NSUInteger blockSize = [[ASDataController class] parallelProcessorCount] * kASDataControllerSizingCountPerProcessor;
|
||||
@ -141,6 +117,27 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutLoadedNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths {
|
||||
NSAssert(NSThread.isMainThread, @"Main thread layout must be on the main thread.");
|
||||
|
||||
[indexPaths enumerateObjectsUsingBlock:^(NSIndexPath *indexPath, NSUInteger idx, __unused BOOL * stop) {
|
||||
ASCellNode *node = nodes[idx];
|
||||
if (node.isNodeLoaded) {
|
||||
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath];
|
||||
[self _layoutNode:node withConstrainedSize:constrainedSize];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* Measure and layout the given node with the constrained size range.
|
||||
*/
|
||||
- (void)_layoutNode:(ASCellNode *)node withConstrainedSize:(ASSizeRange)constrainedSize
|
||||
{
|
||||
[node measureWithSizeRange:constrainedSize];
|
||||
node.frame = CGRectMake(0.0f, 0.0f, node.calculatedSize.width, node.calculatedSize.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures and defines the layout for each node in optimized batches on an editing queue, inserting the results into the backing store.
|
||||
*/
|
||||
@ -176,7 +173,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
for (NSUInteger k = j; k < j + batchCount; k++) {
|
||||
ASCellNode *node = nodes[k];
|
||||
// Only measure nodes whose views aren't loaded, since we're in the background.
|
||||
// We should already have measured loaded nodes before we left the main thread, using _layoutNodesWithMainThreadAffinity:
|
||||
// We should already have measured loaded nodes before we left the main thread, using layoutLoadedNodes:ofKind:atIndexPaths:
|
||||
if (!node.isNodeLoaded) {
|
||||
[self _layoutNode:node withConstrainedSize:nodeBoundSizes[k]];
|
||||
}
|
||||
@ -371,7 +368,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
[self _populateFromEntireDataSourceWithMutableNodes:updatedNodes mutableIndexPaths:updatedIndexPaths];
|
||||
|
||||
// Measure nodes whose views are loaded before we leave the main thread
|
||||
[self _layoutNodesWithMainThreadAffinity:updatedNodes atIndexPaths:updatedIndexPaths];
|
||||
[self layoutLoadedNodes:updatedNodes ofKind:ASDataControllerRowNodeKind atIndexPaths:updatedIndexPaths];
|
||||
|
||||
// Allow subclasses to perform setup before going into the edit transaction
|
||||
[self prepareForReloadData];
|
||||
@ -550,14 +547,14 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
|
||||
|
||||
[self accessDataSourceWithBlock:^{
|
||||
[self prepareForInsertSections:sections];
|
||||
|
||||
NSMutableArray *updatedNodes = [NSMutableArray array];
|
||||
NSMutableArray *updatedIndexPaths = [NSMutableArray array];
|
||||
[self _populateFromDataSourceWithSectionIndexSet:sections mutableNodes:updatedNodes mutableIndexPaths:updatedIndexPaths];
|
||||
|
||||
// Measure nodes whose views are loaded before we leave the main thread
|
||||
[self _layoutNodesWithMainThreadAffinity:updatedNodes atIndexPaths:updatedIndexPaths];
|
||||
[self layoutLoadedNodes:updatedNodes ofKind:ASDataControllerRowNodeKind atIndexPaths:updatedIndexPaths];
|
||||
|
||||
[self prepareForInsertSections:sections];
|
||||
|
||||
[_editingTransactionQueue addOperationWithBlock:^{
|
||||
[self willInsertSections:sections];
|
||||
@ -604,8 +601,6 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
|
||||
|
||||
[self accessDataSourceWithBlock:^{
|
||||
[self prepareForReloadSections:sections];
|
||||
|
||||
NSMutableArray *updatedNodes = [NSMutableArray array];
|
||||
NSMutableArray *updatedIndexPaths = [NSMutableArray array];
|
||||
[self _populateFromDataSourceWithSectionIndexSet:sections mutableNodes:updatedNodes mutableIndexPaths:updatedIndexPaths];
|
||||
@ -615,7 +610,9 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
// at this time. Thus _editingNodes could be empty and crash in ASIndexPathsForMultidimensional[...]
|
||||
|
||||
// Measure nodes whose views are loaded before we leave the main thread
|
||||
[self _layoutNodesWithMainThreadAffinity:updatedNodes atIndexPaths:updatedIndexPaths];
|
||||
[self layoutLoadedNodes:updatedNodes ofKind:ASDataControllerRowNodeKind atIndexPaths:updatedIndexPaths];
|
||||
|
||||
[self prepareForReloadSections:sections];
|
||||
|
||||
[_editingTransactionQueue addOperationWithBlock:^{
|
||||
[self willReloadSections:sections];
|
||||
@ -727,7 +724,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
}
|
||||
|
||||
// Measure nodes whose views are loaded before we leave the main thread
|
||||
[self _layoutNodesWithMainThreadAffinity:nodes atIndexPaths:indexPaths];
|
||||
[self layoutLoadedNodes:nodes ofKind:ASDataControllerRowNodeKind atIndexPaths:indexPaths];
|
||||
|
||||
[_editingTransactionQueue addOperationWithBlock:^{
|
||||
LOG(@"Edit Transaction - insertRows: %@", indexPaths);
|
||||
@ -777,7 +774,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
}
|
||||
|
||||
// Measure nodes whose views are loaded before we leave the main thread
|
||||
[self _layoutNodesWithMainThreadAffinity:nodes atIndexPaths:indexPaths];
|
||||
[self layoutLoadedNodes:nodes ofKind:ASDataControllerRowNodeKind atIndexPaths:indexPaths];
|
||||
|
||||
[_editingTransactionQueue addOperationWithBlock:^{
|
||||
LOG(@"Edit Transaction - reloadRows: %@", indexPaths);
|
||||
|
@ -92,7 +92,12 @@
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return 300;
|
||||
return 10;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
- (void)collectionViewLockDataSource:(ASCollectionView *)collectionView
|
||||
|
Loading…
x
Reference in New Issue
Block a user