mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-04-23 11:27:56 +08:00
[ASDataController] Unify ASDataController and ASCollectionDataController
This commit is contained in:
committed by
Adlai Holler
parent
0bd664f9ed
commit
bb6203347f
@@ -77,7 +77,6 @@
|
||||
205F0E1E1B373A2C007741D0 /* ASCollectionViewLayoutController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E1C1B373A2C007741D0 /* ASCollectionViewLayoutController.mm */; };
|
||||
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CGRect+ASConvenience.m */; };
|
||||
242995D31B29743C00090100 /* ASBasicImageDownloaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */; };
|
||||
251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */; };
|
||||
251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */; };
|
||||
2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */; };
|
||||
254C6B521BF8FE6D003EC431 /* ASTextKitTruncationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 254C6B511BF8FE6D003EC431 /* ASTextKitTruncationTests.mm */; };
|
||||
@@ -249,7 +248,6 @@
|
||||
92DD2FE81BF4D0A80074C9DD /* ASMapNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 92DD2FE11BF4B97E0074C9DD /* ASMapNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
92DD2FE91BF4D4870074C9DD /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92DD2FE51BF4D05E0074C9DD /* MapKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
92DD2FEA1BF4D49B0074C9DD /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92DD2FE51BF4D05E0074C9DD /* MapKit.framework */; };
|
||||
9B92C8851BC2EB6E00EE46B2 /* ASCollectionDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */; };
|
||||
9B92C8861BC2EB7600EE46B2 /* ASCollectionViewFlowLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */; };
|
||||
9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9C55866A1BD549CB00B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; };
|
||||
@@ -263,7 +261,6 @@
|
||||
9C70F2091CDABA36007D6C76 /* ASViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6BF1CCAC73C006A6476 /* ASViewController.mm */; };
|
||||
9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */; };
|
||||
9C70F20B1CDBE9A4007D6C76 /* ASDataController+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */; };
|
||||
9C70F20C1CDBE9B6007D6C76 /* ASCollectionDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */; };
|
||||
9C70F20D1CDBE9CB007D6C76 /* ASDefaultPlayButton.h in Headers */ = {isa = PBXBuildFile; fileRef = AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */; };
|
||||
9C70F20E1CDBE9E5007D6C76 /* NSArray+Diffing.h in Headers */ = {isa = PBXBuildFile; fileRef = DBC452D91C5BF64600B16017 /* NSArray+Diffing.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9C70F20F1CDBE9FF007D6C76 /* ASLayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B30BF6501C5964B0004FCD53 /* ASLayoutManager.h */; };
|
||||
@@ -575,7 +572,6 @@
|
||||
F7CE6C851D2CDB5800BE4C15 /* NSIndexSet+ASHelpers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */; };
|
||||
F7CE6C861D2CDB5800BE4C15 /* _ASDisplayViewAccessiblity.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 69CB62A91CB8165900024920 /* _ASDisplayViewAccessiblity.h */; };
|
||||
F7CE6C871D2CDB5800BE4C15 /* ASDataController+Subclasses.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */; };
|
||||
F7CE6C8B1D2CDB5800BE4C15 /* ASCollectionDataController.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */; };
|
||||
F7CE6C8C1D2CDB5800BE4C15 /* _ASCoreAnimationExtras.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */; };
|
||||
F7CE6C8D1D2CDB5800BE4C15 /* _ASHierarchyChangeSet.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */; };
|
||||
F7CE6C8F1D2CDB5800BE4C15 /* _ASScopeTimer.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 058D0A07195D050800B7D73C /* _ASScopeTimer.h */; };
|
||||
@@ -747,7 +743,6 @@
|
||||
F7CE6C861D2CDB5800BE4C15 /* _ASDisplayViewAccessiblity.h in CopyFiles */,
|
||||
F7CE6C871D2CDB5800BE4C15 /* ASDataController+Subclasses.h in CopyFiles */,
|
||||
F7CE6C451D2CDB3E00BE4C15 /* ASPINRemoteImageDownloader.h in CopyFiles */,
|
||||
F7CE6C8B1D2CDB5800BE4C15 /* ASCollectionDataController.h in CopyFiles */,
|
||||
F7CE6C591D2CDB3E00BE4C15 /* UIView+ASConvenience.h in CopyFiles */,
|
||||
F7CE6C5A1D2CDB3E00BE4C15 /* ASTraitCollection.h in CopyFiles */,
|
||||
F7CE6C8C1D2CDB5800BE4C15 /* _ASCoreAnimationExtras.h in CopyFiles */,
|
||||
@@ -891,8 +886,6 @@
|
||||
205F0E1F1B376416007741D0 /* CGRect+ASConvenience.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CGRect+ASConvenience.h"; sourceTree = "<group>"; };
|
||||
205F0E201B376416007741D0 /* CGRect+ASConvenience.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CGRect+ASConvenience.m"; sourceTree = "<group>"; };
|
||||
242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBasicImageDownloaderTests.m; sourceTree = "<group>"; };
|
||||
251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASCollectionDataController.h; sourceTree = "<group>"; };
|
||||
251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionDataController.mm; sourceTree = "<group>"; };
|
||||
251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewFlowLayoutInspector.h; sourceTree = "<group>"; };
|
||||
251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewFlowLayoutInspector.m; sourceTree = "<group>"; };
|
||||
251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDataController+Subclasses.h"; sourceTree = "<group>"; };
|
||||
@@ -1582,8 +1575,6 @@
|
||||
children = (
|
||||
DE8BEABF1C2DF3FC00D57C12 /* ASDelegateProxy.h */,
|
||||
DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.m */,
|
||||
251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */,
|
||||
251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */,
|
||||
464052191A3F83C40061C0BA /* ASDataController.h */,
|
||||
4640521A1A3F83C40061C0BA /* ASDataController.mm */,
|
||||
AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */,
|
||||
@@ -1725,7 +1716,6 @@
|
||||
AC026B701BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */,
|
||||
B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */,
|
||||
34EFC7631B701CBF00AD841F /* ASCenterLayoutSpec.h in Headers */,
|
||||
9C70F20C1CDBE9B6007D6C76 /* ASCollectionDataController.h in Headers */,
|
||||
18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */,
|
||||
9C8898BD1C738BB800D6B02E /* ASTextKitFontSizeAdjuster.h in Headers */,
|
||||
B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */,
|
||||
@@ -2139,7 +2129,6 @@
|
||||
E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */,
|
||||
058D0A2C195D050800B7D73C /* ASSentinel.m in Sources */,
|
||||
9C8221971BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
||||
251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */,
|
||||
ACF6ED301B17843500DA7C62 /* ASStackLayoutSpec.mm in Sources */,
|
||||
257754BE1BEE458E00737CA5 /* ASTextKitComponents.m in Sources */,
|
||||
257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */,
|
||||
@@ -2228,7 +2217,6 @@
|
||||
92DD2FE71BF4D0850074C9DD /* ASMapNode.mm in Sources */,
|
||||
636EA1A51C7FF4EF00EE152F /* ASDefaultPlayButton.m in Sources */,
|
||||
9B92C8861BC2EB7600EE46B2 /* ASCollectionViewFlowLayoutInspector.m in Sources */,
|
||||
9B92C8851BC2EB6E00EE46B2 /* ASCollectionDataController.mm in Sources */,
|
||||
B350623D1B010EFD0018CF92 /* _ASAsyncTransaction.mm in Sources */,
|
||||
B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */,
|
||||
AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.mm in Sources */,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#import "ASBatchFetching.h"
|
||||
#import "ASDelegateProxy.h"
|
||||
#import "ASCellNode+Internal.h"
|
||||
#import "ASCollectionDataController.h"
|
||||
#import "ASChangeSetDataController.h"
|
||||
#import "ASCollectionViewLayoutController.h"
|
||||
#import "ASCollectionViewFlowLayoutInspector.h"
|
||||
#import "ASDisplayNodeExtras.h"
|
||||
@@ -86,11 +86,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
#pragma mark -
|
||||
#pragma mark ASCollectionView.
|
||||
|
||||
@interface ASCollectionView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASCollectionDataControllerSource, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView, ASDataControllerEnvironmentDelegate> {
|
||||
@interface ASCollectionView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView, ASDataControllerEnvironmentDelegate> {
|
||||
ASCollectionViewProxy *_proxyDataSource;
|
||||
ASCollectionViewProxy *_proxyDelegate;
|
||||
|
||||
ASCollectionDataController *_dataController;
|
||||
ASDataController *_dataController;
|
||||
ASRangeController *_rangeController;
|
||||
ASCollectionViewLayoutController *_layoutController;
|
||||
id<ASCollectionViewLayoutInspecting> _defaultLayoutInspector;
|
||||
@@ -229,7 +229,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
_rangeController.delegate = self;
|
||||
_rangeController.layoutController = _layoutController;
|
||||
|
||||
_dataController = [[ASCollectionDataController alloc] initWithDataSource:self];
|
||||
_dataController = [[ASChangeSetDataController alloc] initWithDataSource:self];
|
||||
_dataController.delegate = _rangeController;
|
||||
_dataController.environmentDelegate = self;
|
||||
|
||||
@@ -1011,24 +1011,24 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
|
||||
#pragma mark - ASCollectionViewDataControllerSource Supplementary view support
|
||||
|
||||
- (ASCellNode *)dataController:(ASCollectionDataController *)dataController supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNode *)dataController:(ASDataController *)dataController supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASCellNode *node = [_asyncDataSource collectionView:self nodeForSupplementaryElementOfKind:kind atIndexPath:indexPath];
|
||||
ASDisplayNodeAssert(node != nil, @"A node must be returned for a supplementary node");
|
||||
return node;
|
||||
}
|
||||
|
||||
- (NSArray *)supplementaryNodeKindsInDataController:(ASCollectionDataController *)dataController
|
||||
- (NSArray *)supplementaryNodeKindsInDataController:(ASDataController *)dataController
|
||||
{
|
||||
return [_registeredSupplementaryKinds allObjects];
|
||||
}
|
||||
|
||||
- (ASSizeRange)dataController:(ASCollectionDataController *)dataController constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASSizeRange)dataController:(ASDataController *)dataController constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [self.layoutInspector collectionView:self constrainedSizeForSupplementaryNodeOfKind:kind atIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (NSUInteger)dataController:(ASCollectionDataController *)dataController supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section
|
||||
- (NSUInteger)dataController:(ASDataController *)dataController supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section
|
||||
{
|
||||
return [self.layoutInspector collectionView:self supplementaryNodesOfKind:kind inSection:section];
|
||||
}
|
||||
|
||||
@@ -57,6 +57,21 @@ FOUNDATION_EXPORT NSString * const ASDataControllerRowNodeKind;
|
||||
*/
|
||||
- (NSUInteger)numberOfSectionsInDataController:(ASDataController *)dataController;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
The constrained size range for layout.
|
||||
*/
|
||||
- (ASSizeRange)dataController:(ASDataController *)dataController constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (NSArray *)supplementaryNodeKindsInDataController:(ASDataController *)dataController;
|
||||
|
||||
- (NSUInteger)dataController:(ASDataController *)dataController supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section;
|
||||
|
||||
- (ASCellNode *)dataController:(ASDataController *)dataController supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (ASCellNodeBlock)dataController:(ASDataController *)dataController supplementaryNodeBlockOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
@end
|
||||
|
||||
@protocol ASDataControllerEnvironmentDelegate
|
||||
@@ -183,6 +198,8 @@ FOUNDATION_EXPORT NSString * const ASDataControllerRowNodeKind;
|
||||
|
||||
- (nullable NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode;
|
||||
|
||||
- (nullable ASCellNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
* Direct access to the nodes that have completed calculation and layout
|
||||
*/
|
||||
|
||||
@@ -59,6 +59,10 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
BOOL _delegateDidDeleteNodes;
|
||||
BOOL _delegateDidInsertSections;
|
||||
BOOL _delegateDidDeleteSections;
|
||||
|
||||
BOOL _dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath;
|
||||
|
||||
NSMutableDictionary<NSString *, NSMutableArray<ASIndexedNodeContext *> *> *_pendingContexts;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -82,6 +86,12 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
_completedNodes[ASDataControllerRowNodeKind] = [NSMutableArray array];
|
||||
_editingNodes[ASDataControllerRowNodeKind] = [NSMutableArray array];
|
||||
|
||||
_pendingContexts = [NSMutableDictionary dictionary];
|
||||
|
||||
_dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath = [dataSource respondsToSelector:@selector(dataController:supplementaryNodeBlockOfKind:atIndexPath:)];
|
||||
|
||||
ASDisplayNodeAssertTrue(_dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath || [dataSource respondsToSelector:@selector(dataController:supplementaryNodeOfKind:atIndexPath:)]);
|
||||
|
||||
_mainSerialQueue = [[ASMainSerialQueue alloc] init];
|
||||
|
||||
const char *queueName = [[NSString stringWithFormat:@"org.AsyncDisplayKit.ASDataController.editingTransactionQueue:%p", self] cStringUsingEncoding:NSASCIIStringEncoding];
|
||||
@@ -217,9 +227,14 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
|
||||
- (ASSizeRange)constrainedSizeForNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [_dataSource dataController:self constrainedSizeForNodeAtIndexPath:indexPath];
|
||||
if ([kind isEqualToString:ASDataControllerRowNodeKind]) {
|
||||
return [_dataSource dataController:self constrainedSizeForNodeAtIndexPath:indexPath];
|
||||
} else {
|
||||
return [_dataSource dataController:self constrainedSizeForSupplementaryNodeOfKind:kind atIndexPath:indexPath];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - External Data Querying + Editing
|
||||
|
||||
- (void)insertNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths completion:(ASDataControllerCompletionBlock)completionBlock
|
||||
@@ -399,7 +414,12 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
NSArray<ASIndexedNodeContext *> *contexts = [self _populateFromDataSourceWithSectionIndexSet:sectionIndexSet];
|
||||
|
||||
// Allow subclasses to perform setup before going into the edit transaction
|
||||
[self prepareForReloadData];
|
||||
for (NSString *kind in [self supplementaryKinds]) {
|
||||
LOG(@"Populating elements of kind: %@", kind);
|
||||
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
|
||||
[self _populateSupplementaryNodesOfKind:kind withMutableContexts:contexts];
|
||||
_pendingContexts[kind] = contexts;
|
||||
}
|
||||
|
||||
dispatch_group_async(_editingTransactionGroup, _editingTransactionQueue, ^{
|
||||
LOG(@"Edit Transaction - reloadData");
|
||||
@@ -414,7 +434,28 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
[self _deleteSectionsAtIndexSet:indexSet withAnimationOptions:animationOptions];
|
||||
}
|
||||
|
||||
[self willReloadData];
|
||||
// Supplementary node handling
|
||||
[_pendingContexts enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull kind, NSMutableArray<ASIndexedNodeContext *> * _Nonnull contexts, __unused BOOL * _Nonnull stop) {
|
||||
// Remove everything that existed before the reload, now that we're ready to insert replacements
|
||||
NSArray *indexPaths = [self indexPathsForEditingNodesOfKind:kind];
|
||||
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
|
||||
NSArray *editingNodes = [self editingNodesOfKind:kind];
|
||||
NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, editingNodes.count)];
|
||||
[self deleteSectionsOfKind:kind atIndexSet:indexSet completion:nil];
|
||||
|
||||
// Insert each section
|
||||
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
|
||||
for (int i = 0; i < sectionCount; i++) {
|
||||
[sections addObject:[NSMutableArray array]];
|
||||
}
|
||||
[self insertSections:sections ofKind:kind atIndexSet:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)] completion:nil];
|
||||
|
||||
[self batchLayoutNodesFromContexts:contexts batchCompletion:^(NSArray<ASCellNode *> *nodes, NSArray<NSIndexPath *> *indexPaths) {
|
||||
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
}];
|
||||
}];
|
||||
[_pendingContexts removeAllObjects];
|
||||
|
||||
// Insert empty sections
|
||||
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
|
||||
@@ -477,6 +518,77 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
return contexts;
|
||||
}
|
||||
|
||||
- (void)_populateSupplementaryNodesOfKind:(NSString *)kind withMutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts
|
||||
{
|
||||
id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment];
|
||||
ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection;
|
||||
|
||||
id<ASDataControllerSource> source = self.dataSource;
|
||||
NSUInteger sectionCount = self.itemCountsFromDataSource.size();
|
||||
for (NSUInteger i = 0; i < sectionCount; i++) {
|
||||
NSUInteger rowCount = [source dataController:self supplementaryNodesOfKind:kind inSection:i];
|
||||
for (NSUInteger j = 0; j < rowCount; j++) {
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:j inSection:i];
|
||||
[self _populateSupplementaryNodeOfKind:kind atIndexPath:indexPath mutableContexts:contexts environmentTraitCollection:environmentTraitCollection];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_populateSupplementaryNodesOfKind:(NSString *)kind withSections:(NSIndexSet *)sections mutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts
|
||||
{
|
||||
id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment];
|
||||
ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection;
|
||||
|
||||
[sections enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
||||
for (NSUInteger sec = range.location; sec < NSMaxRange(range); sec++) {
|
||||
NSUInteger itemCount = [self.dataSource dataController:self supplementaryNodesOfKind:kind inSection:sec];
|
||||
for (NSUInteger i = 0; i < itemCount; i++) {
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:sec];
|
||||
[self _populateSupplementaryNodeOfKind:kind atIndexPath:indexPath mutableContexts:contexts environmentTraitCollection:environmentTraitCollection];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)_populateSupplementaryNodesOfKind:(NSString *)kind atIndexPaths:(NSArray<NSIndexPath *> *)indexPaths mutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts
|
||||
{
|
||||
id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment];
|
||||
ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection;
|
||||
|
||||
NSMutableIndexSet *sections = [NSMutableIndexSet indexSet];
|
||||
for (NSIndexPath *indexPath in indexPaths) {
|
||||
[sections addIndex:indexPath.section];
|
||||
}
|
||||
|
||||
[sections enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
||||
for (NSUInteger sec = range.location; sec < NSMaxRange(range); sec++) {
|
||||
NSUInteger itemCount = [self.dataSource dataController:self supplementaryNodesOfKind:kind inSection:sec];
|
||||
for (NSUInteger i = 0; i < itemCount; i++) {
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:sec];
|
||||
[self _populateSupplementaryNodeOfKind:kind atIndexPath:indexPath mutableContexts:contexts environmentTraitCollection:environmentTraitCollection];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)_populateSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath mutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts environmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection
|
||||
{
|
||||
ASCellNodeBlock supplementaryCellBlock;
|
||||
if (_dataSourceImplementsSupplementaryNodeBlockOfKindAtIndexPath) {
|
||||
supplementaryCellBlock = [self.dataSource dataController:self supplementaryNodeBlockOfKind:kind atIndexPath:indexPath];
|
||||
} else {
|
||||
ASCellNode *supplementaryNode = [self.dataSource dataController:self supplementaryNodeOfKind:kind atIndexPath:indexPath];
|
||||
supplementaryCellBlock = ^{ return supplementaryNode; };
|
||||
}
|
||||
|
||||
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath];
|
||||
ASIndexedNodeContext *context = [[ASIndexedNodeContext alloc] initWithNodeBlock:supplementaryCellBlock
|
||||
indexPath:indexPath
|
||||
constrainedSize:constrainedSize
|
||||
environmentTraitCollection:environmentTraitCollection];
|
||||
[contexts addObject:context];
|
||||
}
|
||||
|
||||
- (void)invalidateDataSourceItemCounts
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
@@ -500,6 +612,13 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
return _itemCountsFromDataSource;
|
||||
}
|
||||
|
||||
#pragma mark - Private Helpers
|
||||
|
||||
- (NSArray *)supplementaryKinds
|
||||
{
|
||||
return [self.dataSource supplementaryNodeKindsInDataController:self];
|
||||
}
|
||||
|
||||
#pragma mark - Batching (External API)
|
||||
|
||||
- (void)beginUpdates
|
||||
@@ -557,10 +676,28 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
|
||||
NSArray<ASIndexedNodeContext *> *contexts = [self _populateFromDataSourceWithSectionIndexSet:sections];
|
||||
|
||||
[self prepareForInsertSections:sections];
|
||||
// Supplementary node handling
|
||||
for (NSString *kind in [self supplementaryKinds]) {
|
||||
LOG(@"Populating elements of kind: %@, for sections: %@", kind, sections);
|
||||
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
|
||||
[self _populateSupplementaryNodesOfKind:kind withSections:sections mutableContexts:contexts];
|
||||
_pendingContexts[kind] = contexts;
|
||||
}
|
||||
|
||||
dispatch_group_async(_editingTransactionGroup, _editingTransactionQueue, ^{
|
||||
[self willInsertSections:sections];
|
||||
// Supplementary node handling
|
||||
[_pendingContexts enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull kind, NSMutableArray<ASIndexedNodeContext *> * _Nonnull contexts, BOOL * _Nonnull stop) {
|
||||
NSMutableArray *sectionArray = [NSMutableArray arrayWithCapacity:sections.count];
|
||||
for (NSUInteger i = 0; i < sections.count; i++) {
|
||||
[sectionArray addObject:[NSMutableArray array]];
|
||||
}
|
||||
|
||||
[self insertSections:sectionArray ofKind:kind atIndexSet:sections completion:nil];
|
||||
[self batchLayoutNodesFromContexts:contexts batchCompletion:^(NSArray<ASCellNode *> *nodes, NSArray<NSIndexPath *> *indexPaths) {
|
||||
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
}];
|
||||
}];
|
||||
[_pendingContexts removeAllObjects];
|
||||
|
||||
LOG(@"Edit Transaction - insertSections: %@", sections);
|
||||
NSMutableArray *sectionArray = [NSMutableArray arrayWithCapacity:sections.count];
|
||||
@@ -584,7 +721,13 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
|
||||
dispatch_group_wait(_editingTransactionGroup, DISPATCH_TIME_FOREVER);
|
||||
dispatch_group_async(_editingTransactionGroup, _editingTransactionQueue, ^{
|
||||
[self willDeleteSections:sections];
|
||||
// Supplementary node handling
|
||||
for (NSString *kind in [self supplementaryKinds]) {
|
||||
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet([self editingNodesOfKind:kind], sections);
|
||||
|
||||
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
[self deleteSectionsOfKind:kind atIndexSet:sections completion:nil];
|
||||
}
|
||||
|
||||
// remove elements
|
||||
LOG(@"Edit Transaction - deleteSections: %@", sections);
|
||||
@@ -611,7 +754,23 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
|
||||
dispatch_group_wait(_editingTransactionGroup, DISPATCH_TIME_FOREVER);
|
||||
dispatch_group_async(_editingTransactionGroup, _editingTransactionQueue, ^{
|
||||
[self willMoveSection:section toSection:newSection];
|
||||
// Supplementary node handling
|
||||
NSIndexSet *sectionAsIndexSet = [NSIndexSet indexSetWithIndex:section];
|
||||
for (NSString *kind in [self supplementaryKinds]) {
|
||||
NSMutableArray *editingNodes = [self editingNodesOfKind:kind];
|
||||
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet(editingNodes, sectionAsIndexSet);
|
||||
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(editingNodes, indexPaths);
|
||||
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
|
||||
// update the section of indexpaths
|
||||
NSMutableArray *updatedIndexPaths = [[NSMutableArray alloc] initWithCapacity:indexPaths.count];
|
||||
for (NSIndexPath *indexPath in indexPaths) {
|
||||
NSUInteger newItem = [indexPath indexAtPosition:indexPath.length - 1];
|
||||
NSIndexPath *mappedIndexPath = [NSIndexPath indexPathForItem:newItem inSection:newSection];
|
||||
[updatedIndexPaths addObject:mappedIndexPath];
|
||||
}
|
||||
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
}
|
||||
|
||||
// remove elements
|
||||
|
||||
@@ -633,59 +792,6 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Backing store manipulation optional hooks (Subclass API)
|
||||
|
||||
- (void)prepareForReloadData
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)willReloadData
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)prepareForInsertSections:(NSIndexSet *)sections
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)willInsertSections:(NSIndexSet *)sections
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)willDeleteSections:(NSIndexSet *)sections
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)prepareForInsertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)willInsertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)prepareForDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
- (void)willDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
|
||||
{
|
||||
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
|
||||
}
|
||||
|
||||
#pragma mark - Row Editing (External API)
|
||||
|
||||
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
@@ -714,10 +820,23 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
environmentTraitCollection:environmentTraitCollection]];
|
||||
}
|
||||
|
||||
[self prepareForInsertRowsAtIndexPaths:indexPaths];
|
||||
// Supplementary node handling
|
||||
for (NSString *kind in [self supplementaryKinds]) {
|
||||
LOG(@"Populating elements of kind: %@, for index paths: %@", kind, indexPaths);
|
||||
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
|
||||
[self _populateSupplementaryNodesOfKind:kind atIndexPaths:indexPaths mutableContexts:contexts];
|
||||
_pendingContexts[kind] = contexts;
|
||||
}
|
||||
|
||||
dispatch_group_async(_editingTransactionGroup, _editingTransactionQueue, ^{
|
||||
[self willInsertRowsAtIndexPaths:indexPaths];
|
||||
// Supplementary node handling
|
||||
[_pendingContexts enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull kind, NSMutableArray<ASIndexedNodeContext *> * _Nonnull contexts, BOOL * _Nonnull stop) {
|
||||
[self batchLayoutNodesFromContexts:contexts batchCompletion:^(NSArray<ASCellNode *> *nodes, NSArray<NSIndexPath *> *indexPaths) {
|
||||
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
}];
|
||||
}];
|
||||
|
||||
[_pendingContexts removeAllObjects];
|
||||
|
||||
LOG(@"Edit Transaction - insertRows: %@", indexPaths);
|
||||
[self _batchLayoutAndInsertNodesFromContexts:contexts withAnimationOptions:animationOptions];
|
||||
@@ -740,10 +859,34 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
// FIXME: Shouldn't deletes be sorted in descending order?
|
||||
NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)];
|
||||
|
||||
[self prepareForDeleteRowsAtIndexPaths:sortedIndexPaths];
|
||||
// Supplementary node handling
|
||||
for (NSString *kind in [self supplementaryKinds]) {
|
||||
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
|
||||
[self _populateSupplementaryNodesOfKind:kind atIndexPaths:indexPaths mutableContexts:contexts];
|
||||
_pendingContexts[kind] = contexts;
|
||||
}
|
||||
|
||||
dispatch_group_async(_editingTransactionGroup, _editingTransactionQueue, ^{
|
||||
[self willDeleteRowsAtIndexPaths:sortedIndexPaths];
|
||||
// Supplementary node handling
|
||||
for (NSString *kind in [self supplementaryKinds]) {
|
||||
NSArray<NSIndexPath *> *deletedIndexPaths = ASIndexPathsInMultidimensionalArrayIntersectingIndexPaths([self editingNodesOfKind:kind], indexPaths);
|
||||
|
||||
[self deleteNodesOfKind:kind atIndexPaths:deletedIndexPaths completion:nil];
|
||||
|
||||
// If any of the contexts remain after the deletion, re-insert them, e.g.
|
||||
// UICollectionElementKindSectionHeader remains even if item 0 is deleted.
|
||||
NSMutableArray<ASIndexedNodeContext *> *reinsertedContexts = [NSMutableArray array];
|
||||
for (ASIndexedNodeContext *context in _pendingContexts[kind]) {
|
||||
if ([deletedIndexPaths containsObject:context.indexPath]) {
|
||||
[reinsertedContexts addObject:context];
|
||||
}
|
||||
}
|
||||
|
||||
[self batchLayoutNodesFromContexts:reinsertedContexts batchCompletion:^(NSArray<ASCellNode *> *nodes, NSArray<NSIndexPath *> *indexPaths) {
|
||||
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
|
||||
}];
|
||||
}
|
||||
[_pendingContexts removeAllObjects];
|
||||
|
||||
LOG(@"Edit Transaction - deleteRows: %@", indexPaths);
|
||||
[self _deleteNodesAtIndexPaths:sortedIndexPaths withAnimationOptions:animationOptions];
|
||||
@@ -890,6 +1033,21 @@ NSString * const ASDataControllerRowNodeKind = @"_ASDataControllerRowNodeKind";
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (ASCellNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
NSArray *nodesOfKind = [self completedNodesOfKind:kind];
|
||||
NSInteger section = indexPath.section;
|
||||
if (section < nodesOfKind.count) {
|
||||
NSArray *nodesOfKindInSection = nodesOfKind[section];
|
||||
NSInteger itemIndex = indexPath.item;
|
||||
if (itemIndex < nodesOfKindInSection.count) {
|
||||
return nodesOfKindInSection[itemIndex];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
/// Returns nodes that can be queried externally. _externalCompletedNodes is used if available, _completedNodes otherwise.
|
||||
- (NSArray *)completedNodes
|
||||
{
|
||||
|
||||
@@ -86,113 +86,4 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCellNode *> *nodes, NS
|
||||
*/
|
||||
- (void)deleteSectionsOfKind:(NSString *)kind atIndexSet:(NSIndexSet *)indexSet completion:(void (^)(NSIndexSet *indexSet))completionBlock;
|
||||
|
||||
#pragma mark - Data Manipulation Hooks
|
||||
|
||||
/**
|
||||
* Notifies the subclass to perform any work needed before the data controller is reloaded entirely
|
||||
*
|
||||
* @discussion This method will be performed before the data controller enters its editing queue.
|
||||
* The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
|
||||
* data stores before entering into editing the backing store on a background thread.
|
||||
*/
|
||||
- (void)prepareForReloadData;
|
||||
|
||||
/**
|
||||
* Notifies the subclass that the data controller is about to reload its data entirely
|
||||
*
|
||||
* @discussion This method will be performed on the data controller's editing background queue before the parent's
|
||||
* concrete implementation. This is a great place to perform new node creation like supplementary views
|
||||
* or header/footer nodes.
|
||||
*/
|
||||
- (void)willReloadData;
|
||||
|
||||
/**
|
||||
* Notifies the subclass to perform setup before sections are inserted in the data controller
|
||||
*
|
||||
* @discussion This method will be performed before the data controller enters its editing queue.
|
||||
* The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
|
||||
* data stores before entering into editing the backing store on a background thread.
|
||||
*
|
||||
* @param sections Indices of sections to be inserted
|
||||
*/
|
||||
- (void)prepareForInsertSections:(NSIndexSet *)sections;
|
||||
|
||||
/**
|
||||
* Notifies the subclass that the data controller will insert new sections at the given position
|
||||
*
|
||||
* @discussion This method will be performed on the data controller's editing background queue before the parent's
|
||||
* concrete implementation. This is a great place to perform any additional transformations like supplementary views
|
||||
* or header/footer nodes.
|
||||
*
|
||||
* @param sections Indices of sections to be inserted
|
||||
*/
|
||||
- (void)willInsertSections:(NSIndexSet *)sections;
|
||||
|
||||
/**
|
||||
* Notifies the subclass that the data controller will delete sections at the given positions
|
||||
*
|
||||
* @discussion This method will be performed on the data controller's editing background queue before the parent's
|
||||
* concrete implementation. This is a great place to perform any additional transformations like supplementary views
|
||||
* or header/footer nodes.
|
||||
*
|
||||
* @param sections Indices of sections to be deleted
|
||||
*/
|
||||
- (void)willDeleteSections:(NSIndexSet *)sections;
|
||||
|
||||
/**
|
||||
* Notifies the subclass that the data controller will move a section to a new position
|
||||
*
|
||||
* @discussion This method will be performed on the data controller's editing background queue before the parent's
|
||||
* concrete implementation. This is a great place to perform any additional transformations like supplementary views
|
||||
* or header/footer nodes.
|
||||
*
|
||||
* @param section Index of current section position
|
||||
* @param newSection Index of new section position
|
||||
*/
|
||||
- (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection;
|
||||
|
||||
/**
|
||||
* Notifies the subclass to perform setup before rows are inserted in the data controller.
|
||||
*
|
||||
* @discussion This method will be performed before the data controller enters its editing queue.
|
||||
* The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
|
||||
* data stores before entering into editing the backing store on a background thread.
|
||||
*
|
||||
* @param indexPaths Index paths for the rows to be inserted.
|
||||
*/
|
||||
- (void)prepareForInsertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
|
||||
|
||||
/**
|
||||
* Notifies the subclass that the data controller will insert new rows at the given index paths.
|
||||
*
|
||||
* @discussion This method will be performed on the data controller's editing background queue before the parent's
|
||||
* concrete implementation. This is a great place to perform any additional transformations like supplementary views
|
||||
* or header/footer nodes.
|
||||
*
|
||||
* @param indexPaths Index paths for the rows to be inserted.
|
||||
*/
|
||||
- (void)willInsertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
|
||||
|
||||
/**
|
||||
* Notifies the subclass to perform setup before rows are deleted in the data controller.
|
||||
*
|
||||
* @discussion This method will be performed before the data controller enters its editing queue.
|
||||
* The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
|
||||
* data stores before entering into editing the backing store on a background thread.
|
||||
*
|
||||
* @param indexPaths Index paths for the rows to be deleted.
|
||||
*/
|
||||
- (void)prepareForDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
|
||||
|
||||
/**
|
||||
* Notifies the subclass that the data controller will delete rows at the given index paths.
|
||||
*
|
||||
* @discussion This method will be performed before the data controller enters its editing queue.
|
||||
* The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
|
||||
* data stores before entering into editing the backing store on a background thread.
|
||||
*
|
||||
* @param indexPaths Index paths for the rows to be deleted.
|
||||
*/
|
||||
- (void)willDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "ASCollectionView.h"
|
||||
#import "ASCollectionDataController.h"
|
||||
#import "ASDataController.h"
|
||||
#import "ASCollectionViewFlowLayoutInspector.h"
|
||||
#import "ASCellNode.h"
|
||||
#import "ASCollectionNode.h"
|
||||
@@ -108,7 +108,7 @@
|
||||
|
||||
@interface ASCollectionView (InternalTesting)
|
||||
|
||||
- (NSArray *)supplementaryNodeKindsInDataController:(ASCollectionDataController *)dataController;
|
||||
- (NSArray *)supplementaryNodeKindsInDataController:(ASDataController *)dataController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user