Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

Commit

Permalink
[ASCollectionView / ASPagerNode] Move constrainedSizeForNodeAtIndexPa…
Browse files Browse the repository at this point in the history
…th from the DataSource to the Delegate (#2065)

* Move constrainedSizeForNodeAtIndexPath from the DataSource to the Delegate in ASCollectionView and ASPagerNode

* Fix ASPagerNode declaration of dataSource and delegate

As ASPagerDataSource does not inherit from ASCollectionDataSource it's not possible to declare it as property.

* Update comment
  • Loading branch information
maicki authored and Adlai Holler committed Aug 12, 2016
1 parent 2c9e51e commit 93be894
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 50 deletions.
22 changes: 11 additions & 11 deletions AsyncDisplayKit/ASCollectionView.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,17 +400,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;

/**
* Provides the constrained size range for measuring the node at the index path.
*
* @param collectionView The sender.
*
* @param indexPath The index path of the node.
*
* @returns A constrained size range for layout the node at this index path.
*/
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath;

/**
* Indicator to lock the data source for data fetching in async mode.
* We should not update the data source until the data source has been unlocked. Otherwise, it will incur data inconsistency or exception
Expand Down Expand Up @@ -442,6 +431,17 @@ NS_ASSUME_NONNULL_BEGIN

@optional

/**
* Provides the constrained size range for measuring the node at the index path.
*
* @param collectionView The sender.
*
* @param indexPath The index path of the node.
*
* @returns A constrained size range for layout the node at this index path.
*/
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath;

/**
* Informs the delegate that the collection view will add the node
* at the given index path to the view hierarchy.
Expand Down
4 changes: 0 additions & 4 deletions AsyncDisplayKit/ASCollectionView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,9 @@ @interface ASCollectionView () <ASRangeControllerDataSource, ASRangeControllerDe
} _asyncDelegateFlags;

struct {
unsigned int asyncDataSourceConstrainedSizeForNode:1;
unsigned int asyncDataSourceNodeForItemAtIndexPath:1;
unsigned int asyncDataSourceNodeBlockForItemAtIndexPath:1;
unsigned int asyncDataSourceNumberOfSectionsInCollectionView:1;
unsigned int asyncDataSourceCollectionViewConstrainedSizeForNodeAtIndexPath:1;
} _asyncDataSourceFlags;

struct {
Expand Down Expand Up @@ -354,11 +352,9 @@ - (void)setAsyncDataSource:(id<ASCollectionViewDataSource>)asyncDataSource
_asyncDataSource = asyncDataSource;
_proxyDataSource = [[ASCollectionViewProxy alloc] initWithTarget:_asyncDataSource interceptor:self];

_asyncDataSourceFlags.asyncDataSourceConstrainedSizeForNode = [_asyncDataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];
_asyncDataSourceFlags.asyncDataSourceNodeForItemAtIndexPath = [_asyncDataSource respondsToSelector:@selector(collectionView:nodeForItemAtIndexPath:)];
_asyncDataSourceFlags.asyncDataSourceNodeBlockForItemAtIndexPath = [_asyncDataSource respondsToSelector:@selector(collectionView:nodeBlockForItemAtIndexPath:)];
_asyncDataSourceFlags.asyncDataSourceNumberOfSectionsInCollectionView = [_asyncDataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)];
_asyncDataSourceFlags.asyncDataSourceCollectionViewConstrainedSizeForNodeAtIndexPath = [_asyncDataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];

// Data-source must implement collectionView:nodeForItemAtIndexPath: or collectionView:nodeBlockForItemAtIndexPath:
ASDisplayNodeAssertTrue(_asyncDataSourceFlags.asyncDataSourceNodeBlockForItemAtIndexPath || _asyncDataSourceFlags.asyncDataSourceNodeForItemAtIndexPath);
Expand Down
23 changes: 15 additions & 8 deletions AsyncDisplayKit/ASPagerNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
@class ASPagerNode;
@class ASPagerFlowLayout;

NS_ASSUME_NONNULL_BEGIN

#define ASPagerNodeDataSource ASPagerDataSource
@protocol ASPagerDataSource <NSObject>

Expand Down Expand Up @@ -52,6 +54,12 @@
*/
- (ASCellNodeBlock)pagerNode:(ASPagerNode *)pagerNode nodeBlockAtIndex:(NSInteger)index;

@end

@protocol ASPagerDelegate <ASCollectionDelegate>

@optional

/**
* Provides the constrained size range for measuring the node at the index path.
*
Expand All @@ -63,10 +71,6 @@

@end

@protocol ASPagerDelegate <ASCollectionDelegate>

@end

@interface ASPagerNode : ASCollectionNode

/**
Expand All @@ -82,14 +86,15 @@
/**
* Data Source is required, and uses a different protocol from ASCollectionNode.
*/
- (void)setDataSource:(id <ASPagerDataSource>)dataSource;
- (id <ASPagerDataSource>)dataSource;
- (void)setDataSource:(nullable id <ASPagerDataSource>)dataSource;
- (nullable id <ASPagerDataSource>)dataSource;

/**
* Delegate is optional, and uses the same protocol as ASCollectionNode.
* Delegate is optional.
* This includes UIScrollViewDelegate as well as most methods from UICollectionViewDelegate, like willDisplay...
*/
@property (nonatomic, weak) id <ASPagerDelegate> delegate;
- (void)setDelegate:(nullable id <ASPagerDelegate>)delegate;
- (nullable id <ASPagerDelegate>)delegate;

/**
* The underlying ASCollectionView object.
Expand All @@ -112,3 +117,5 @@
- (ASCellNode *)nodeForPageAtIndex:(NSInteger)index;

@end

NS_ASSUME_NONNULL_END
43 changes: 31 additions & 12 deletions AsyncDisplayKit/ASPagerNode.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@
#import "ASDisplayNode+Subclasses.h"
#import "ASPagerFlowLayout.h"

@interface ASPagerNode () <ASCollectionDataSource, ASCollectionViewDelegateFlowLayout, ASDelegateProxyInterceptor>
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionDelegate, ASCollectionViewDelegateFlowLayout, ASDelegateProxyInterceptor>
{
ASPagerFlowLayout *_flowLayout;
ASPagerNodeProxy *_proxy;
__weak id <ASPagerNodeDataSource> _pagerDataSource;

__weak id <ASPagerDataSource> _pagerDataSource;
ASPagerNodeProxy *_proxyDataSource;
BOOL _pagerDataSourceImplementsNodeBlockAtIndex;
BOOL _pagerDataSourceImplementsConstrainedSizeForNode;

__weak id <ASPagerDelegate> _pagerDelegate;
ASPagerNodeProxy *_proxyDelegate;
BOOL _pagerDelegateImplementsConstrainedSizeForNode;
}

@end

@implementation ASPagerNode

@dynamic view, delegate, dataSource;

#pragma mark - Lifecycle
Expand Down Expand Up @@ -58,6 +63,7 @@ - (void)didLoad
[super didLoad];

ASCollectionView *cv = self.view;
cv.asyncDelegate = self;
#if TARGET_OS_IOS
cv.pagingEnabled = YES;
cv.scrollsToTop = NO;
Expand Down Expand Up @@ -122,9 +128,10 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSe

- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
{
if (_pagerDataSourceImplementsConstrainedSizeForNode) {
return [_pagerDataSource pagerNode:self constrainedSizeForNodeAtIndexPath:indexPath];
if (_pagerDelegateImplementsConstrainedSizeForNode) {
return [_pagerDelegate pagerNode:self constrainedSizeForNodeAtIndexPath:indexPath];
}

return ASSizeRangeMake(CGSizeZero, self.view.bounds.size);
}

Expand All @@ -135,26 +142,38 @@ - (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSize
return _pagerDataSource;
}

- (void)setDataSource:(id <ASPagerDataSource>)pagerDataSource
- (void)setDataSource:(id <ASPagerDataSource>)dataSource
{
if (pagerDataSource != _pagerDataSource) {
_pagerDataSource = pagerDataSource;
if (dataSource != _pagerDataSource) {
_pagerDataSource = dataSource;

_pagerDataSourceImplementsNodeBlockAtIndex = [_pagerDataSource respondsToSelector:@selector(pagerNode:nodeBlockAtIndex:)];
// Data source must implement pagerNode:nodeBlockAtIndex: or pagerNode:nodeAtIndex:
ASDisplayNodeAssertTrue(_pagerDataSourceImplementsNodeBlockAtIndex || [_pagerDataSource respondsToSelector:@selector(pagerNode:nodeAtIndex:)]);

_pagerDataSourceImplementsConstrainedSizeForNode = [_pagerDataSource respondsToSelector:@selector(pagerNode:constrainedSizeForNodeAtIndexPath:)];
_proxyDataSource = dataSource ? [[ASPagerNodeProxy alloc] initWithTarget:dataSource interceptor:self] : nil;

super.dataSource = (id <ASCollectionDataSource>)_proxyDataSource;
}
}

- (void)setDelegate:(id<ASPagerDelegate>)delegate
{
if (delegate != _pagerDelegate) {
_pagerDelegate = delegate;

_pagerDelegateImplementsConstrainedSizeForNode = [_pagerDelegate respondsToSelector:@selector(pagerNode:constrainedSizeForNodeAtIndexPath:)];

_proxy = pagerDataSource ? [[ASPagerNodeProxy alloc] initWithTarget:pagerDataSource interceptor:self] : nil;
_proxyDelegate = delegate ? [[ASPagerNodeProxy alloc] initWithTarget:delegate interceptor:self] : nil;

super.dataSource = (id <ASCollectionDataSource>)_proxy;
super.delegate = (id <ASCollectionDelegate>)_proxyDelegate;
}
}

- (void)proxyTargetHasDeallocated:(ASDelegateProxy *)proxy
{
[self setDataSource:nil];
[self setDelegate:nil];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
@protocol ASCollectionViewLayoutInspecting <NSObject>

/**
* Asks the inspector to provide a constarained size range for the given collection view node.
* Asks the inspector to provide a constrained size range for the given collection view node.
*/
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath;

Expand Down
24 changes: 12 additions & 12 deletions AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView
@implementation ASCollectionViewLayoutInspector {
struct {
unsigned int implementsConstrainedSizeForNodeAtIndexPath:1;
} _dataSourceFlags;
} _delegateFlags;
}

#pragma mark Lifecycle
Expand All @@ -43,26 +43,26 @@ - (instancetype)initWithCollectionView:(ASCollectionView *)collectionView
{
self = [super init];
if (self != nil) {
[self didChangeCollectionViewDataSource:collectionView.asyncDataSource];
[self didChangeCollectionViewDelegate:collectionView.asyncDelegate];
}
return self;
}

#pragma mark ASCollectionViewLayoutInspecting

- (void)didChangeCollectionViewDataSource:(id<ASCollectionDataSource>)dataSource
- (void)didChangeCollectionViewDelegate:(id<ASCollectionDelegate>)delegate
{
if (dataSource == nil) {
memset(&_dataSourceFlags, 0, sizeof(_dataSourceFlags));
if (delegate == nil) {
memset(&_delegateFlags, 0, sizeof(_delegateFlags));
} else {
_dataSourceFlags.implementsConstrainedSizeForNodeAtIndexPath = [dataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];
_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath = [delegate respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];
}
}

- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
{
if (_dataSourceFlags.implementsConstrainedSizeForNodeAtIndexPath) {
return [collectionView.asyncDataSource collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath];
if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath) {
return [collectionView.asyncDelegate collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath];
}

return NodeConstrainedSizeForScrollDirection(collectionView);
Expand Down Expand Up @@ -99,10 +99,10 @@ @implementation ASCollectionViewFlowLayoutInspector {
struct {
unsigned int implementsReferenceSizeForHeader:1;
unsigned int implementsReferenceSizeForFooter:1;
unsigned int implementsConstrainedSizeForNodeAtIndexPath:1;
} _delegateFlags;

struct {
unsigned int implementsConstrainedSizeForNodeAtIndexPath:1;
unsigned int implementsNumberOfSectionsInCollectionView:1;
} _dataSourceFlags;
}
Expand Down Expand Up @@ -132,6 +132,7 @@ - (void)didChangeCollectionViewDelegate:(id<ASCollectionDelegate>)delegate;
} else {
_delegateFlags.implementsReferenceSizeForHeader = [delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForHeaderInSection:)];
_delegateFlags.implementsReferenceSizeForFooter = [delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForFooterInSection:)];
_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath = [delegate respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];
}
}

Expand All @@ -140,15 +141,14 @@ - (void)didChangeCollectionViewDataSource:(id<ASCollectionDataSource>)dataSource
if (dataSource == nil) {
memset(&_dataSourceFlags, 0, sizeof(_dataSourceFlags));
} else {
_dataSourceFlags.implementsConstrainedSizeForNodeAtIndexPath = [dataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)];
_dataSourceFlags.implementsNumberOfSectionsInCollectionView = [dataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)];
}
}

- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
{
if (_dataSourceFlags.implementsConstrainedSizeForNodeAtIndexPath) {
return [collectionView.asyncDataSource collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath];
if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath) {
return [collectionView.asyncDelegate collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath];
}

CGSize itemSize = _layout.itemSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize

#pragma mark - OverviewASPagerNode

@interface OverviewASPagerNode () <ASPagerNodeDataSource>
@interface OverviewASPagerNode () <ASPagerDataSource, ASPagerDelegate>
@property (nonatomic, strong) ASPagerNode *node;
@property (nonatomic, copy) NSArray *data;
@end
Expand All @@ -61,6 +61,7 @@ - (instancetype)init

_node = [ASPagerNode new];
_node.dataSource = self;
_node.delegate = self;
[self addSubnode:_node];

return self;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#import "ViewController.h"
#import "GradientTableNode.h"

@interface ViewController () <ASPagerNodeDataSource>
@interface ViewController () <ASPagerDataSource, ASPagerDelegate>
{
ASPagerNode *_pagerNode;
}
Expand All @@ -38,6 +38,7 @@ - (instancetype)init

_pagerNode = [[ASPagerNode alloc] init];
_pagerNode.dataSource = self;
_pagerNode.delegate = self;
[ASRangeController setShouldShowRangeDebugOverlay:YES];

// Could implement ASCollectionDelegate if we wanted extra callbacks, like from UIScrollView.
Expand Down

0 comments on commit 93be894

Please sign in to comment.