diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 9ac3062590..60926d0444 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -185,6 +185,9 @@ 68B8A4E21CBDB958007E4543 /* ASWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */; }; 68B8A4E31CBDB958007E4543 /* ASWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */; }; 68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */; }; + 68C215581DE10D330019C4BC /* ASCollectionViewLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 68C215591DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */; }; + 68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */; }; 68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */; }; 68EE0DBF1C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; }; 68EE0DC01C1B4ED300BA1B99 /* ASMainSerialQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */; }; @@ -992,6 +995,8 @@ 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+AnimatedImagePrivate.h"; sourceTree = ""; }; 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakProxy.h; sourceTree = ""; }; 68B8A4E01CBDB958007E4543 /* ASWeakProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakProxy.m; sourceTree = ""; }; + 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutInspector.h; sourceTree = ""; }; + 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewLayoutInspector.m; sourceTree = ""; }; 68EE0DBB1C1B4ED300BA1B99 /* ASMainSerialQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMainSerialQueue.h; sourceTree = ""; }; 68EE0DBC1C1B4ED300BA1B99 /* ASMainSerialQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMainSerialQueue.mm; sourceTree = ""; }; 68FC85DC1CE29AB700EDD713 /* ASNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASNavigationController.h; sourceTree = ""; }; @@ -1493,6 +1498,8 @@ 054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */, 299DA1A71A828D2900162D41 /* ASBatchContext.h */, 299DA1A81A828D2900162D41 /* ASBatchContext.mm */, + 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */, + 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */, 251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */, 251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */, 205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */, @@ -1822,6 +1829,7 @@ DE89C1741DCEB9CC00D49D74 /* ASLayoutElementInspectorNode.h in Headers */, B13CA1011C52004900E031AB /* ASCollectionNode+Beta.h in Headers */, 254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */, + 68C215581DE10D330019C4BC /* ASCollectionViewLayoutInspector.h in Headers */, B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */, B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */, B350620F1B010EFD0018CF92 /* _ASDisplayLayer.h in Headers */, @@ -2018,12 +2026,15 @@ isa = PBXNativeTarget; buildConfigurationList = 058D09D2195D04C000B7D73C /* Build configuration list for PBXNativeTarget "AsyncDisplayKitTests" */; buildPhases = ( + A5D6EC8A55F2AA9E9EE68B07 /* 📦 Check Pods Manifest.lock */, 2E61B6A0DB0F436A9DDBE86F /* [CP] Check Pods Manifest.lock */, 058D09B8195D04C000B7D73C /* Sources */, 058D09B9195D04C000B7D73C /* Frameworks */, 058D09BA195D04C000B7D73C /* Resources */, 3B9D88CDF51B429C8409E4B6 /* [CP] Copy Pods Resources */, B130AB1AC0A1E5162E211C19 /* [CP] Embed Pods Frameworks */, + 3BFEAD5C584653624B1B9F75 /* 📦 Embed Pods Frameworks */, + 2F77738278748228F6400335 /* 📦 Copy Pods Resources */, ); buildRules = ( ); @@ -2139,6 +2150,21 @@ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; + 2F77738278748228F6400335 /* 📦 Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "📦 Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 3B9D88CDF51B429C8409E4B6 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2154,6 +2180,36 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 3BFEAD5C584653624B1B9F75 /* 📦 Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "📦 Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A5D6EC8A55F2AA9E9EE68B07 /* 📦 Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "📦 Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; B130AB1AC0A1E5162E211C19 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2296,6 +2352,7 @@ ACF6ED321B17843500DA7C62 /* ASAbsoluteLayoutSpec.mm in Sources */, AC026B6B1BD57D6F00BBC17E /* ASChangeSetDataController.mm in Sources */, 68355B311CB5799E001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */, + 68C215591DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */, 9CFFC6C01CCAC73C006A6476 /* ASViewController.mm in Sources */, 055F1A3519ABD3E3004DAFF1 /* ASTableView.mm in Sources */, 6959433E1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */, @@ -2486,6 +2543,7 @@ AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.mm in Sources */, 34EFC7741B701D0A00AD841F /* ASAbsoluteLayoutSpec.mm in Sources */, 92074A6A1CC8BADA00918F75 /* ASControlNode+tvOS.m in Sources */, + 68C2155A1DE10D330019C4BC /* ASCollectionViewLayoutInspector.m in Sources */, DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.m in Sources */, B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */, B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */, diff --git a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h index 7453acb4b7..52df1ee1d4 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h +++ b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h @@ -10,78 +10,10 @@ #pragma once -#import -#import -#import - -@class ASCollectionView; -@protocol ASCollectionDataSource; -@protocol ASCollectionDelegate; +#include "ASCollectionViewLayoutInspector.h" NS_ASSUME_NONNULL_BEGIN -@protocol ASCollectionViewLayoutInspecting - -/** - * Asks the inspector to provide a constrained size range for the given collection view node. - */ -- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath; - -/** - * Return the directions in which your collection view can scroll - */ -- (ASScrollDirection)scrollableDirections; - -@optional - -/** - * Asks the inspector to provide a constrained size range for the given supplementary node. - */ -- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath; - -/** - * Asks the inspector for the number of supplementary views for the given kind in the specified section. - */ -- (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:(nullable id)delegate; - -/** - * Allow the inspector to respond to dataSource changes. - * - * @discussion A great time to update perform selector caches! - */ -- (void)didChangeCollectionViewDataSource:(nullable id)dataSource; - -#pragma mark Deprecated Methods - -/** - * Asks the inspector for the number of supplementary sections in the collection view for the given kind. - * - * @deprecated This method will not be called, and it is only deprecated as a reminder to remove it. - * Supplementary elements must exist in the same sections as regular collection view items i.e. -numberOfSectionsInCollectionView: - */ -- (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryNodeOfKind:(NSString *)kind ASDISPLAYNODE_DEPRECATED_MSG("Use ASCollectionNode's method instead."); - -@end - -/** - * A layout inspector for non-flow layouts that returns a constrained size to let the cells layout itself as - * far as possible based on the scrollable direction of the collection view. It throws exceptions for delegate - * methods that are related to supplementary node's management. - */ -@interface ASCollectionViewLayoutInspector : NSObject - -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView NS_DESIGNATED_INITIALIZER; - -@end - /** * A layout inspector implementation specific for the sizing behavior of UICollectionViewFlowLayouts */ diff --git a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m index 7f0e1911c7..5c49d17ea2 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m +++ b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m @@ -16,90 +16,6 @@ #define kDefaultItemSize CGSizeMake(50, 50) -#pragma mark - Helper Functions - -// Returns a constrained size to let the cells layout itself as far as possible based on the scrollable direction -// of the collection view -static inline ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView) { - CGSize maxSize = collectionView.bounds.size; - if (ASScrollDirectionContainsHorizontalDirection(collectionView.scrollableDirections)) { - maxSize.width = CGFLOAT_MAX; - } else { - maxSize.height = CGFLOAT_MAX; - } - return ASSizeRangeMake(CGSizeZero, maxSize); -} - -#pragma mark - ASCollectionViewLayoutInspector - -@implementation ASCollectionViewLayoutInspector { - struct { - unsigned int implementsConstrainedSizeForNodeAtIndexPathDeprecated:1; - unsigned int implementsConstrainedSizeForNodeAtIndexPath:1; - } _delegateFlags; -} - -#pragma mark Lifecycle - -- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView -{ - self = [super init]; - if (self != nil) { - [self didChangeCollectionViewDelegate:collectionView.asyncDelegate]; - } - return self; -} - -#pragma mark ASCollectionViewLayoutInspecting - -- (void)didChangeCollectionViewDelegate:(id)delegate -{ - if (delegate == nil) { - memset(&_delegateFlags, 0, sizeof(_delegateFlags)); - } else { - _delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated = [delegate respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)]; - _delegateFlags.implementsConstrainedSizeForNodeAtIndexPath = [delegate respondsToSelector:@selector(collectionNode:constrainedSizeForItemAtIndexPath:)]; - } -} - -- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath -{ - if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath) { - return [collectionView.asyncDelegate collectionNode:collectionView.collectionNode constrainedSizeForItemAtIndexPath:indexPath]; - } else if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - return [collectionView.asyncDelegate collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath]; -#pragma clang diagnostic pop - } else { - // With 2.0 `collectionView:constrainedSizeForNodeAtIndexPath:` was moved to the delegate. Assert if not implemented on the delegate but on the data source - ASDisplayNodeAssert([collectionView.asyncDataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)] == NO, @"collectionView:constrainedSizeForNodeAtIndexPath: was moved from the ASCollectionDataSource to the ASCollectionDelegate."); - } - - return NodeConstrainedSizeForScrollDirection(collectionView); -} - -- (ASScrollDirection)scrollableDirections -{ - ASDisplayNodeAssert(NO, @"layoutInspector object must implement -scrollableDirections %@", self); - return ASScrollDirectionNone; -} - -- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath -{ - ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)"); - return ASSizeRangeMake(CGSizeZero, CGSizeZero); -} - -- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section -{ - ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)"); - return 0; -} - -@end - - #pragma mark - ASCollectionViewFlowLayoutInspector @interface ASCollectionViewFlowLayoutInspector () diff --git a/AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.h b/AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.h new file mode 100644 index 0000000000..5b8c901218 --- /dev/null +++ b/AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.h @@ -0,0 +1,83 @@ +// +// ASCollectionViewLayoutInspector.h +// AsyncDisplayKit +// +// Created by Garrett Moon on 11/19/16. +// Copyright © 2016 Facebook. All rights reserved. +// + +#import +#import +#import + +@class ASCollectionView; +@protocol ASCollectionDataSource; +@protocol ASCollectionDelegate; + +NS_ASSUME_NONNULL_BEGIN + +extern ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView); + +@protocol ASCollectionViewLayoutInspecting + +/** + * Asks the inspector to provide a constrained size range for the given collection view node. + */ +- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath; + +/** + * Return the directions in which your collection view can scroll + */ +- (ASScrollDirection)scrollableDirections; + +@optional + +/** + * Asks the inspector to provide a constrained size range for the given supplementary node. + */ +- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath; + +/** + * Asks the inspector for the number of supplementary views for the given kind in the specified section. + */ +- (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:(nullable id)delegate; + +/** + * Allow the inspector to respond to dataSource changes. + * + * @discussion A great time to update perform selector caches! + */ +- (void)didChangeCollectionViewDataSource:(nullable id)dataSource; + +#pragma mark Deprecated Methods + +/** + * Asks the inspector for the number of supplementary sections in the collection view for the given kind. + * + * @deprecated This method will not be called, and it is only deprecated as a reminder to remove it. + * Supplementary elements must exist in the same sections as regular collection view items i.e. -numberOfSectionsInCollectionView: + */ +- (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryNodeOfKind:(NSString *)kind ASDISPLAYNODE_DEPRECATED_MSG("Use ASCollectionNode's method instead."); + +@end + +/** + * A layout inspector for non-flow layouts that returns a constrained size to let the cells layout itself as + * far as possible based on the scrollable direction of the collection view. It throws exceptions for delegate + * methods that are related to supplementary node's management. + */ +@interface ASCollectionViewLayoutInspector : NSObject + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.m b/AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.m new file mode 100644 index 0000000000..d55b6506ac --- /dev/null +++ b/AsyncDisplayKit/Details/ASCollectionViewLayoutInspector.m @@ -0,0 +1,95 @@ +// +// ASCollectionViewLayoutInspector.m +// AsyncDisplayKit +// +// Created by Garrett Moon on 11/19/16. +// Copyright © 2016 Facebook. All rights reserved. +// + +#import "ASCollectionViewLayoutInspector.h" + +#import "ASCollectionView.h" +#import "ASCollectionView+Undeprecated.h" + +#pragma mark - Helper Functions + +// Returns a constrained size to let the cells layout itself as far as possible based on the scrollable direction +// of the collection view +ASSizeRange NodeConstrainedSizeForScrollDirection(ASCollectionView *collectionView) { + CGSize maxSize = collectionView.bounds.size; + if (ASScrollDirectionContainsHorizontalDirection(collectionView.scrollableDirections)) { + maxSize.width = CGFLOAT_MAX; + } else { + maxSize.height = CGFLOAT_MAX; + } + return ASSizeRangeMake(CGSizeZero, maxSize); +} + +#pragma mark - ASCollectionViewLayoutInspector + +@implementation ASCollectionViewLayoutInspector { + struct { + unsigned int implementsConstrainedSizeForNodeAtIndexPathDeprecated:1; + unsigned int implementsConstrainedSizeForNodeAtIndexPath:1; + } _delegateFlags; +} + +#pragma mark Lifecycle + +- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView +{ + self = [super init]; + if (self != nil) { + [self didChangeCollectionViewDelegate:collectionView.asyncDelegate]; + } + return self; +} + +#pragma mark ASCollectionViewLayoutInspecting + +- (void)didChangeCollectionViewDelegate:(id)delegate +{ + if (delegate == nil) { + memset(&_delegateFlags, 0, sizeof(_delegateFlags)); + } else { + _delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated = [delegate respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)]; + _delegateFlags.implementsConstrainedSizeForNodeAtIndexPath = [delegate respondsToSelector:@selector(collectionNode:constrainedSizeForItemAtIndexPath:)]; + } +} + +- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath +{ + if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPath) { + return [collectionView.asyncDelegate collectionNode:collectionView.collectionNode constrainedSizeForItemAtIndexPath:indexPath]; + } else if (_delegateFlags.implementsConstrainedSizeForNodeAtIndexPathDeprecated) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return [collectionView.asyncDelegate collectionView:collectionView constrainedSizeForNodeAtIndexPath:indexPath]; +#pragma clang diagnostic pop + } else { + // With 2.0 `collectionView:constrainedSizeForNodeAtIndexPath:` was moved to the delegate. Assert if not implemented on the delegate but on the data source + ASDisplayNodeAssert([collectionView.asyncDataSource respondsToSelector:@selector(collectionView:constrainedSizeForNodeAtIndexPath:)] == NO, @"collectionView:constrainedSizeForNodeAtIndexPath: was moved from the ASCollectionDataSource to the ASCollectionDelegate."); + } + + return NodeConstrainedSizeForScrollDirection(collectionView); +} + +- (ASScrollDirection)scrollableDirections +{ + ASDisplayNodeAssert(NO, @"layoutInspector object must implement -scrollableDirections %@", self); + return ASScrollDirectionNone; +} + +- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath +{ + ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)"); + return ASSizeRangeMake(CGSizeZero, CGSizeZero); +} + +- (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryNodesOfKind:(NSString *)kind inSection:(NSUInteger)section +{ + ASDisplayNodeAssert(NO, @"To support supplementary nodes in ASCollectionView, it must have a layoutInspector for layout inspection. (See ASCollectionViewFlowLayoutInspector for an example.)"); + return 0; +} + +@end