From 73ddebed81b48d38b29f2f846556b35320b1b765 Mon Sep 17 00:00:00 2001 From: Levi McCallum Date: Tue, 29 Sep 2015 18:01:20 -0700 Subject: [PATCH] Implement UICollectionViewFlowLayout heuristics in a default inspector --- AsyncDisplayKit/ASCollectionView.mm | 35 ++++---- .../ASCollectionViewFlowLayoutInspector.h | 9 ++ .../ASCollectionViewFlowLayoutInspector.m | 83 ++++++++++++++++--- 3 files changed, 99 insertions(+), 28 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 1e4154852f..a91be86ecd 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -688,21 +688,6 @@ static BOOL _isInterceptedSelector(SEL sel) return [_asyncDataSource collectionView:self numberOfItemsInSection:section]; } -- (ASSizeRange)dataController:(ASCollectionDataController *)dataController constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath -{ - return [self.layoutDelegate collectionView:self constrainedSizeForSupplementaryNodeOfKind:kind atIndexPath:indexPath]; -} - -- (NSUInteger)dataController:(ASCollectionDataController *)dataController supplementaryViewsOfKind:(NSString *)kind inSection:(NSUInteger)section -{ - return [self.layoutDelegate collectionView:self supplementaryViewsOfKind:kind inSection:section]; -} - -- (NSUInteger)dataController:(ASCollectionDataController *)dataController numberOfSectionsForSupplementaryKind:(NSString *)kind; -{ - return [self.layoutDelegate collectionView:self numberOfSectionsForSupplementaryKind:kind]; -} - - (NSUInteger)numberOfSectionsInDataController:(ASDataController *)dataController { if ([_asyncDataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)]) { return [_asyncDataSource numberOfSectionsInCollectionView:self]; @@ -731,8 +716,24 @@ static BOOL _isInterceptedSelector(SEL sel) } } -#pragma mark - -#pragma mark ASRangeControllerDelegate. +#pragma mark - ASCollectionViewDataControllerSource Supplementary view support + +- (ASSizeRange)dataController:(ASCollectionDataController *)dataController constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath +{ + return [_layoutDelegate collectionView:self constrainedSizeForSupplementaryNodeOfKind:kind atIndexPath:indexPath]; +} + +- (NSUInteger)dataController:(ASCollectionDataController *)dataController supplementaryViewsOfKind:(NSString *)kind inSection:(NSUInteger)section +{ + return [_layoutDelegate collectionView:self supplementaryViewsOfKind:kind inSection:section]; +} + +- (NSUInteger)dataController:(ASCollectionDataController *)dataController numberOfSectionsForSupplementaryKind:(NSString *)kind; +{ + return [_layoutDelegate collectionView:self numberOfSectionsForSupplementaryKind:kind]; +} + +#pragma mark - ASRangeControllerDelegate. - (void)rangeControllerBeginUpdates:(ASRangeController *)rangeController { ASDisplayNodeAssertMainThread(); diff --git a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h index e28ff0878f..962b6bfd18 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h +++ b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.h @@ -14,10 +14,19 @@ @protocol ASCollectionViewLayoutInspecting +/** + * Asks the inspector + */ - (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath; +/** + * Asks the inspector for the number of supplementary sections in the collection view for the given kind. + */ - (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryKind:(NSString *)kind; +/** + * Asks the inspector for the number of supplementary views for the given kind in the specified section. + */ - (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryViewsOfKind:(NSString *)kind inSection:(NSUInteger)section; @end diff --git a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m index 0a0b1598dc..d8cbd2fa7e 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m +++ b/AsyncDisplayKit/Details/ASCollectionViewFlowLayoutInspector.m @@ -6,32 +6,93 @@ // // +#import + #import "ASCollectionViewFlowLayoutInspector.h" #import "ASCollectionView.h" -@implementation ASCollectionViewFlowLayoutInspector +@implementation ASCollectionViewFlowLayoutInspector { + BOOL _delegateImplementsReferenceSizeForHeader; + BOOL _delegateImplementsReferenceSizeForFooter; +} + +#pragma mark - Accessors + +- (void)setLayout:(UICollectionViewFlowLayout *)layout +{ + _layout = layout; + _delegateImplementsReferenceSizeForHeader = [[self layoutDelegate] respondsToSelector:@selector(collectionView:layout:referenceSizeForHeaderInSection:)]; + _delegateImplementsReferenceSizeForFooter = [[self layoutDelegate] respondsToSelector:@selector(collectionView:layout:referenceSizeForFooterInSection:)]; +} + +#pragma mark - ASCollectionViewLayoutInspecting - (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForSupplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { - // TODO: Implement some heuristic that follows the width/height constraints of header and footer supplementary views - return ASSizeRangeMake(CGSizeZero, CGSizeMake(FLT_MAX, FLT_MAX)); + CGSize constrainedSize = CGSizeMake(FLT_MAX, FLT_MAX); + CGSize supplementarySize = [self sizeForSupplementaryViewOfKind:kind inSection:indexPath.section]; + if (_layout.scrollDirection == UICollectionViewScrollDirectionVertical) { + constrainedSize.height = supplementarySize.height; + } else { + constrainedSize.width = supplementarySize.width; + } + return ASSizeRangeMake(CGSizeZero, constrainedSize); } -- (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryKind:(NSString *)kind { - return self.collectionView.numberOfSections; +- (NSUInteger)collectionView:(ASCollectionView *)collectionView numberOfSectionsForSupplementaryKind:(NSString *)kind +{ + return [collectionView.asyncDataSource numberOfSectionsInCollectionView:collectionView]; } - (NSUInteger)collectionView:(ASCollectionView *)collectionView supplementaryViewsOfKind:(NSString *)kind inSection:(NSUInteger)section { - NSUInteger count = 0; - if (self.layout.headerReferenceSize.width > 0 || self.layout.headerReferenceSize.height > 0) { - count++; + return [self layoutHasSupplementaryViewOfKind:kind inSection:section] ? 1 : 0; +} + +#pragma mark - Private helpers + +- (CGSize)sizeForSupplementaryViewOfKind:(NSString *)kind inSection:(NSUInteger)section +{ + if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { + if (_delegateImplementsReferenceSizeForHeader) { + return [[self layoutDelegate] collectionView:_collectionView layout:_layout referenceSizeForHeaderInSection:section]; + } else { + return [self.layout headerReferenceSize]; + } + } else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) { + if (_delegateImplementsReferenceSizeForFooter) { + return [[self layoutDelegate] collectionView:_collectionView layout:_layout referenceSizeForFooterInSection:section]; + } else { + return [self.layout footerReferenceSize]; + } + } else { + return CGSizeZero; } - if (self.layout.footerReferenceSize.width > 0 || self.layout.footerReferenceSize.height > 0) { - count++; +} + +- (BOOL)layoutHasSupplementaryViewOfKind:(NSString *)kind inSection:(NSUInteger)section +{ + CGSize size = [self sizeForSupplementaryViewOfKind:kind inSection:section]; + if ([self usedLayoutValueForSize:size] > 0) { + return YES; + } else { + return NO; } - return count; +} + +- (CGFloat)usedLayoutValueForSize:(CGSize)size +{ + if (_layout.scrollDirection == UICollectionViewScrollDirectionVertical) { + return size.height; + } else { + return size.width; + } +} + +- (id)layoutDelegate +{ + return (id)self.collectionView.delegate; } @end