diff --git a/AsyncDisplayKit/ASCollectionView.h b/AsyncDisplayKit/ASCollectionView.h index 62f508f1..afe74f5e 100644 --- a/AsyncDisplayKit/ASCollectionView.h +++ b/AsyncDisplayKit/ASCollectionView.h @@ -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 @@ -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. diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 5e71ffd4..7d222eae 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -151,11 +151,9 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } _asyncDelegateFlags; struct { - unsigned int asyncDataSourceConstrainedSizeForNode:1; unsigned int asyncDataSourceNodeForItemAtIndexPath:1; unsigned int asyncDataSourceNodeBlockForItemAtIndexPath:1; unsigned int asyncDataSourceNumberOfSectionsInCollectionView:1; - unsigned int asyncDataSourceCollectionViewConstrainedSizeForNodeAtIndexPath:1; } _asyncDataSourceFlags; struct { @@ -354,11 +352,9 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; _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); diff --git a/AsyncDisplayKit/ASPagerNode.h b/AsyncDisplayKit/ASPagerNode.h index 21b5d698..1b028b02 100644 --- a/AsyncDisplayKit/ASPagerNode.h +++ b/AsyncDisplayKit/ASPagerNode.h @@ -16,6 +16,8 @@ @class ASPagerNode; @class ASPagerFlowLayout; +NS_ASSUME_NONNULL_BEGIN + #define ASPagerNodeDataSource ASPagerDataSource @protocol ASPagerDataSource @@ -52,6 +54,12 @@ */ - (ASCellNodeBlock)pagerNode:(ASPagerNode *)pagerNode nodeBlockAtIndex:(NSInteger)index; +@end + +@protocol ASPagerDelegate + +@optional + /** * Provides the constrained size range for measuring the node at the index path. * @@ -63,10 +71,6 @@ @end -@protocol ASPagerDelegate - -@end - @interface ASPagerNode : ASCollectionNode /** @@ -82,14 +86,15 @@ /** * Data Source is required, and uses a different protocol from ASCollectionNode. */ -- (void)setDataSource:(id )dataSource; -- (id )dataSource; +- (void)setDataSource:(nullable id )dataSource; +- (nullable id )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 delegate; +- (void)setDelegate:(nullable id )delegate; +- (nullable id )delegate; /** * The underlying ASCollectionView object. @@ -112,3 +117,5 @@ - (ASCellNode *)nodeForPageAtIndex:(NSInteger)index; @end + +NS_ASSUME_NONNULL_END diff --git a/AsyncDisplayKit/ASPagerNode.m b/AsyncDisplayKit/ASPagerNode.m index b5050f4d..47704098 100644 --- a/AsyncDisplayKit/ASPagerNode.m +++ b/AsyncDisplayKit/ASPagerNode.m @@ -15,18 +15,23 @@ #import "ASDisplayNode+Subclasses.h" #import "ASPagerFlowLayout.h" -@interface ASPagerNode () +@interface ASPagerNode () { ASPagerFlowLayout *_flowLayout; - ASPagerNodeProxy *_proxy; - __weak id _pagerDataSource; + + __weak id _pagerDataSource; + ASPagerNodeProxy *_proxyDataSource; BOOL _pagerDataSourceImplementsNodeBlockAtIndex; - BOOL _pagerDataSourceImplementsConstrainedSizeForNode; + + __weak id _pagerDelegate; + ASPagerNodeProxy *_proxyDelegate; + BOOL _pagerDelegateImplementsConstrainedSizeForNode; } @end @implementation ASPagerNode + @dynamic view, delegate, dataSource; #pragma mark - Lifecycle @@ -58,6 +63,7 @@ [super didLoad]; ASCollectionView *cv = self.view; + cv.asyncDelegate = self; #if TARGET_OS_IOS cv.pagingEnabled = YES; cv.scrollsToTop = NO; @@ -122,9 +128,10 @@ - (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); } @@ -135,26 +142,38 @@ return _pagerDataSource; } -- (void)setDataSource:(id )pagerDataSource +- (void)setDataSource:(id )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; - _proxy = pagerDataSource ? [[ASPagerNodeProxy alloc] initWithTarget:pagerDataSource interceptor:self] : nil; + super.dataSource = (id )_proxyDataSource; + } +} + +- (void)setDelegate:(id)delegate +{ + if (delegate != _pagerDelegate) { + _pagerDelegate = delegate; - super.dataSource = (id )_proxy; + _pagerDelegateImplementsConstrainedSizeForNode = [_pagerDelegate respondsToSelector:@selector(pagerNode:constrainedSizeForNodeAtIndexPath:)]; + + _proxyDelegate = delegate ? [[ASPagerNodeProxy alloc] initWithTarget:delegate interceptor:self] : nil; + + super.delegate = (id )_proxyDelegate; } } - (void)proxyTargetHasDeallocated:(ASDelegateProxy *)proxy { [self setDataSource:nil]; + [self setDelegate:nil]; } @end diff --git a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h index 423c8302..608a93ce 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h +++ b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol ASCollectionViewLayoutInspecting /** - * 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; diff --git a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m index 25ba06b7..9ae4d1e1 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m +++ b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m @@ -34,7 +34,7 @@ static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView @implementation ASCollectionViewLayoutInspector { struct { unsigned int implementsConstrainedSizeForNodeAtIndexPath:1; - } _dataSourceFlags; + } _delegateFlags; } #pragma mark Lifecycle @@ -43,26 +43,26 @@ static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView { self = [super init]; if (self != nil) { - [self didChangeCollectionViewDataSource:collectionView.asyncDataSource]; + [self didChangeCollectionViewDelegate:collectionView.asyncDelegate]; } return self; } #pragma mark ASCollectionViewLayoutInspecting -- (void)didChangeCollectionViewDataSource:(id)dataSource +- (void)didChangeCollectionViewDelegate:(id)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); @@ -99,10 +99,10 @@ static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView struct { unsigned int implementsReferenceSizeForHeader:1; unsigned int implementsReferenceSizeForFooter:1; + unsigned int implementsConstrainedSizeForNodeAtIndexPath:1; } _delegateFlags; struct { - unsigned int implementsConstrainedSizeForNodeAtIndexPath:1; unsigned int implementsNumberOfSectionsInCollectionView:1; } _dataSourceFlags; } @@ -132,6 +132,7 @@ static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView } else { _delegateFlags.implementsReferenceSizeForHeader = [delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForHeaderInSection:)]; _delegateFlags.implementsReferenceSizeForFooter = [delegate respondsToSelector:@selector(collectionView:layout:referenceSizeForFooterInSection:)]; + _delegateFlags.implementsConstrainedSizeForNodeAtIndexPath = [delegate respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)]; } } @@ -140,15 +141,14 @@ static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView 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; diff --git a/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASPagerNode.m b/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASPagerNode.m index 8b7f39d8..b2a4499b 100644 --- a/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASPagerNode.m +++ b/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASPagerNode.m @@ -47,7 +47,7 @@ static UIColor *OverViewASPagerNodeRandomColor() { #pragma mark - OverviewASPagerNode -@interface OverviewASPagerNode () +@interface OverviewASPagerNode () @property (nonatomic, strong) ASPagerNode *node; @property (nonatomic, copy) NSArray *data; @end @@ -61,6 +61,7 @@ static UIColor *OverViewASPagerNodeRandomColor() { _node = [ASPagerNode new]; _node.dataSource = self; + _node.delegate = self; [self addSubnode:_node]; return self; diff --git a/examples/VerticalWithinHorizontalScrolling/Sample/ViewController.m b/examples/VerticalWithinHorizontalScrolling/Sample/ViewController.m index 74a5f53c..a0db6621 100644 --- a/examples/VerticalWithinHorizontalScrolling/Sample/ViewController.m +++ b/examples/VerticalWithinHorizontalScrolling/Sample/ViewController.m @@ -19,7 +19,7 @@ #import "ViewController.h" #import "GradientTableNode.h" -@interface ViewController () +@interface ViewController () { ASPagerNode *_pagerNode; } @@ -38,6 +38,7 @@ _pagerNode = [[ASPagerNode alloc] init]; _pagerNode.dataSource = self; + _pagerNode.delegate = self; // Could implement ASCollectionDelegate if we wanted extra callbacks, like from UIScrollView. //_pagerNode.delegate = self;