Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AsyncDisplayKit/ASCollectionView.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
* collection view layout subclasses will need to provide their own implementation of an inspector object for their
* supplementary views to be compatible with `ASCollectionView`'s supplementary node support.
*/
@property (nonatomic, weak) id<ASCollectionViewLayoutInspecting> layoutDelegate;
@property (nonatomic, weak) id<ASCollectionViewLayoutInspecting> layoutInspector;

/**
* Perform a batch of updates asynchronously, optionally disabling all animations in the batch. This method must be called from the main thread.
Expand Down
32 changes: 12 additions & 20 deletions AsyncDisplayKit/ASCollectionView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ @interface ASCollectionView () <ASRangeControllerDelegate, ASDataControllerSourc
CGSize _maxSizeForNodesConstrainedSize;
BOOL _ignoreMaxSizeChange;

NSMutableArray *_registeredSupplementaryKinds;
NSMutableSet *_registeredSupplementaryKinds;

/**
* If YES, the `UICollectionView` will reload its data on next layout pass so we should not forward any updates to it.
Expand Down Expand Up @@ -229,10 +229,10 @@ - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionVi
// Register the default layout inspector delegate for flow layouts only, custom layouts
// will need to roll their own ASCollectionViewLayoutInspecting implementation and set a layout delegate
if ([layout asdk_isFlowLayout]) {
_layoutDelegate = [self flowLayoutInspector];
_layoutInspector = [self flowLayoutInspector];
}

_registeredSupplementaryKinds = [NSMutableArray array];
_registeredSupplementaryKinds = [NSMutableSet set];

self.backgroundColor = [UIColor whiteColor];

Expand All @@ -256,6 +256,7 @@ - (ASCollectionViewFlowLayoutInspector *)flowLayoutInspector
{
if (_flowLayoutInspector == nil) {
UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionViewLayout;
ASDisplayNodeAssertNotNil(layout, @"Collection view layout must be a flow layout to use the built-in inspector");
_flowLayoutInspector = [[ASCollectionViewFlowLayoutInspector alloc] initWithCollectionView:self
flowLayout:layout];
}
Expand Down Expand Up @@ -333,16 +334,7 @@ - (void)setAsyncDelegate:(id<ASCollectionViewDelegate>)asyncDelegate
_asyncDelegateImplementsInsetSection = ([_asyncDelegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)] ? 1 : 0);
}

[_flowLayoutInspector cacheSelectorsForCollectionView:self];
}

- (void)setCollectionViewLayout:(UICollectionViewLayout *)collectionViewLayout
{
[super setCollectionViewLayout:collectionViewLayout];
if ([collectionViewLayout asdk_isFlowLayout]) {
_flowLayoutInspector = nil;
_layoutDelegate = [self flowLayoutInspector];
}
[_layoutInspector didChangeCollectionViewDelegate:asyncDelegate];
}

- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
Expand Down Expand Up @@ -745,25 +737,25 @@ - (ASCellNode *)dataController:(ASCollectionDataController *)dataController supp

- (NSArray *)supplementaryNodeKindsInDataController:(ASCollectionDataController *)dataController
{
return _registeredSupplementaryKinds;
return [_registeredSupplementaryKinds allObjects];
}

- (ASSizeRange)dataController:(ASCollectionDataController *)dataController constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
ASDisplayNodeAssert(_layoutDelegate != nil, @"To support supplementary nodes in ASCollectionView, it must have a layoutDelegate for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
return [_layoutDelegate collectionView:self constrainedSizeForSupplementaryNodeOfKind:kind atIndexPath:indexPath];
ASDisplayNodeAssert(_layoutInspector != nil, @"To support supplementary nodes in ASCollectionView, it must have a layoutDelegate for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
return [_layoutInspector collectionView:self constrainedSizeForSupplementaryNodeOfKind:kind atIndexPath:indexPath];
}

- (NSUInteger)dataController:(ASCollectionDataController *)dataController supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section
{
ASDisplayNodeAssert(_layoutDelegate != nil, @"To support supplementary nodes in ASCollectionView, it must have a layoutDelegate for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
return [_layoutDelegate collectionView:self supplementaryNodesOfKind:kind inSection:section];
ASDisplayNodeAssert(_layoutInspector != nil, @"To support supplementary nodes in ASCollectionView, it must have a layoutDelegate for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
return [_layoutInspector collectionView:self supplementaryNodesOfKind:kind inSection:section];
}

- (NSUInteger)dataController:(ASCollectionDataController *)dataController numberOfSectionsForSupplementaryNodeOfKind:(NSString *)kind;
{
ASDisplayNodeAssert(_layoutDelegate != nil, @"To support supplementary nodes in ASCollectionView, it must have a layoutDelegate for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
return [_layoutDelegate collectionView:self numberOfSectionsForSupplementaryNodeOfKind:kind];
ASDisplayNodeAssert(_layoutInspector != nil, @"To support supplementary nodes in ASCollectionView, it must have a layoutDelegate for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)");
return [_layoutInspector collectionView:self numberOfSectionsForSupplementaryNodeOfKind:kind];
}

#pragma mark - ASRangeControllerDelegate.
Expand Down
2 changes: 1 addition & 1 deletion AsyncDisplayKit/Details/ASCollectionDataController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ - (void)willReloadData
NSUInteger sectionCount = [self.collectionDataSource dataController:self numberOfSectionsForSupplementaryNodeOfKind:kind];
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
for (int i = 0; i < sectionCount; i++) {
[sections addObject:[[NSMutableArray alloc] init]];
[sections addObject:[NSMutableArray array]];
}
[self insertSections:sections ofKind:kind atIndexSet:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)] completion:nil];

Expand Down
10 changes: 8 additions & 2 deletions AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import <AsyncDisplayKit/ASDimension.h>

@class ASCollectionView;
@protocol ASCollectionViewDelegate;

@protocol ASCollectionViewLayoutInspecting <NSObject>

Expand All @@ -29,6 +30,13 @@
*/
- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section;

/**
* Allow the inspector to respond to delegate changes.
*
* @discussion A great time to update perform selector caches!
*/
- (void)didChangeCollectionViewDelegate:(id<ASCollectionViewDelegate>)delegate;

@end

@interface ASCollectionViewFlowLayoutInspector : NSObject <ASCollectionViewLayoutInspecting>
Expand All @@ -37,6 +45,4 @@

- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView flowLayout:(UICollectionViewFlowLayout *)flowLayout;

- (void)cacheSelectorsForCollectionView:(ASCollectionView *)collectionView;

@end
18 changes: 10 additions & 8 deletions AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#import "ASCollectionViewFlowLayoutInspector.h"

#import "ASCollectionView.h"
#import "ASAssert.h"
#import "ASEqualityHelpers.h"

@implementation ASCollectionViewFlowLayoutInspector {
BOOL _delegateImplementsReferenceSizeForHeader;
Expand All @@ -24,24 +26,24 @@ - (instancetype)initWithCollectionView:(ASCollectionView *)collectionView flowLa
self = [super init];

if (flowLayout == nil) {
return nil;
ASDisplayNodeAssert(NO, @"Should never create a layout inspector without a layout");
}

if (self != nil) {
[self cacheSelectorsForCollectionView:collectionView];
[self didChangeCollectionViewDelegate:collectionView.asyncDelegate];
_layout = flowLayout;
}
return self;
}

- (void)cacheSelectorsForCollectionView:(ASCollectionView *)collectionView
- (void)didChangeCollectionViewDelegate:(id<ASCollectionViewDelegate>)delegate;
{
if (collectionView == nil) {
if (delegate == nil) {
_delegateImplementsReferenceSizeForHeader = NO;
_delegateImplementsReferenceSizeForFooter = NO;
} else {
_delegateImplementsReferenceSizeForHeader = [[self delegateForCollectionView:collectionView] respondsToSelector:@selector(collectionView:layout:referenceSizeForHeaderInSection:)];
_delegateImplementsReferenceSizeForFooter = [[self delegateForCollectionView:collectionView] respondsToSelector:@selector(collectionView:layout:referenceSizeForFooterInSection:)];
_delegateImplementsReferenceSizeForHeader = [delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForHeaderInSection:)];
_delegateImplementsReferenceSizeForFooter = [delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForFooterInSection:)];
}
}

Expand Down Expand Up @@ -77,13 +79,13 @@ - (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNod

- (CGSize)sizeForSupplementaryViewOfKind:(NSString *)kind inSection:(NSUInteger)section collectionView:(ASCollectionView *)collectionView
{
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
if (ASObjectIsEqual(kind, UICollectionElementKindSectionHeader)) {
if (_delegateImplementsReferenceSizeForHeader) {
return [[self delegateForCollectionView:collectionView] collectionView:collectionView layout:_layout referenceSizeForHeaderInSection:section];
} else {
return [self.layout headerReferenceSize];
}
} else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
} else if (ASObjectIsEqual(kind, UICollectionElementKindSectionFooter)) {
if (_delegateImplementsReferenceSizeForFooter) {
return [[self delegateForCollectionView:collectionView] collectionView:collectionView layout:_layout referenceSizeForFooterInSection:section];
} else {
Expand Down
8 changes: 4 additions & 4 deletions AsyncDisplayKit/Details/ASDataController+Subclasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@
/**
* 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, usually on the main
* thread. The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
* @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;
Expand All @@ -92,8 +92,8 @@
/**
* 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, usually on the main
* thread. The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
* @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
Expand Down
14 changes: 9 additions & 5 deletions AsyncDisplayKit/Details/ASDataController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import "ASDisplayNode.h"
#import "ASMultidimensionalArrayUtils.h"
#import "ASDisplayNodeInternal.h"
#import "ASLayout.h"

//#define LOG(...) NSLog(__VA_ARGS__)
#define LOG(...)
Expand Down Expand Up @@ -185,8 +186,9 @@ - (void)_layoutNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSAr
dispatch_group_wait(layoutGroup, DISPATCH_TIME_FOREVER);
free(nodeBoundSizes);

if (completionBlock)
if (completionBlock) {
completionBlock(nodes, indexPaths);
}
}

- (ASSizeRange)constrainedSizeForNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
Expand Down Expand Up @@ -218,8 +220,10 @@ - (void)insertNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArr

- (void)deleteNodesOfKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths completion:(void (^)(NSArray *nodes, NSArray *indexPaths))completionBlock
{
if (indexPaths.count == 0)
if (indexPaths.count == 0) {
return;
}

LOG(@"_deleteNodesAtIndexPaths:%@ ofKind:%@, full index paths in _editingNodes = %@", indexPaths, kind, ASIndexPathsForMultidimensionalArray(_editingNodes[kind]));
NSMutableArray *editingNodes = _editingNodes[kind];
ASDeleteElementsInMultidimensionalArrayAtIndexPaths(editingNodes, indexPaths);
Expand Down Expand Up @@ -818,8 +822,8 @@ - (void)_relayoutNodesOfKind:(NSString *)kind
[section enumerateObjectsUsingBlock:^(ASCellNode *node, NSUInteger rowIndex, BOOL *stop) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath];
[node measureWithSizeRange:constrainedSize];
node.frame = CGRectMake(0.0f, 0.0f, node.calculatedSize.width, node.calculatedSize.height);
ASLayout *layout = [node measureWithSizeRange:constrainedSize];
node.frame = CGRectMake(0.0f, 0.0f, layout.size.width, layout.size.height);
}];
}];
}];
Expand Down Expand Up @@ -849,7 +853,7 @@ - (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)n

- (NSArray *)indexPathsForEditingNodesOfKind:(NSString *)kind
{
return _editingNodes[kind] != nil ? ASIndexPathsForMultidimensionalArray(_editingNodes[kind]) : [NSArray array];
return _editingNodes[kind] != nil ? ASIndexPathsForMultidimensionalArray(_editingNodes[kind]) : nil;
}

- (NSMutableArray *)editingNodesOfKind:(NSString *)kind
Expand Down
6 changes: 3 additions & 3 deletions AsyncDisplayKitTests/ASCollectionViewTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@ - (void)testThatItSetsALayoutInspectorForFlowLayouts
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
ASCollectionView *collectionView = [[ASCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
XCTAssert(collectionView.layoutDelegate != nil, @"should automatically set a layout delegate for flow layouts");
XCTAssert([collectionView.layoutDelegate isKindOfClass:[ASCollectionViewFlowLayoutInspector class]], @"should have a flow layout inspector by default");
XCTAssert(collectionView.layoutInspector != nil, @"should automatically set a layout delegate for flow layouts");
XCTAssert([collectionView.layoutInspector isKindOfClass:[ASCollectionViewFlowLayoutInspector class]], @"should have a flow layout inspector by default");
}

- (void)testThatItDoesNotSetALayoutInspectorForCustomLayouts
{
UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init];
ASCollectionView *collectionView = [[ASCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
XCTAssert(collectionView.layoutDelegate == nil, @"should not set a layout delegate for custom layouts");
XCTAssert(collectionView.layoutInspector == nil, @"should not set a layout delegate for custom layouts");
}

- (void)testThatRegisteringASupplementaryNodeStoresItForIntrospection
Expand Down