123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- //
- // BYHLabelsLayout.m
- // UICollectionVIewDemo
- //
- // Created by 疯叶 on 2019/8/14.
- // Copyright © 2019 疯叶. All rights reserved.
- //
- #import "BYHLabelsLayout.h"
- /** 每一列之间的间距 */
- static const CGFloat BYHMinimumLineSpacing = 10;
- /** 每一行之间的间距 */
- static const CGFloat BYHMinimumInterSpacing = 10;
- /** 边缘间距 */
- static const UIEdgeInsets XHLDefaultEdgeInsets = {10, 10, 10, 10};
- /** 头部高度 */
- static const CGFloat BYHHeaderHeight = 0;
- /** 尾部高度 */
- static const CGFloat BYHFooterHeight = 0;
- @interface BYHLabelsLayout ()
- /** 存放所有cell的布局属性 */
- @property (nonatomic, strong) NSMutableArray *itemAttrsArray;
- /** 存放所有Header的布局属性 */
- @property (nonatomic, strong) NSMutableArray *headerAttrsArr;
- /** 存放所有Footer的布局属性 */
- @property (nonatomic, strong) NSMutableArray *footerAttrsArr;
- /** 存放所有列的当前高度 */
- @property (nonatomic, strong) NSMutableArray *columnHeights;
- /** 内容的高度 */
- @property (nonatomic, assign) CGFloat contentHeight;
- /** 内容的宽度 */
- @property (nonatomic, assign) CGFloat itemMaxX;
- /** item的最大高度 */
- @property (nonatomic, assign) CGFloat itemMaxHeight;
- /** 上次布局的section*/
- @property (nonatomic, assign) NSInteger nextSection;
- @end
- @implementation BYHLabelsLayout
- #pragma mark - 代理数据处理
- - (CGFloat)minimumInterWithSection:(NSInteger)section {
- if ([self.delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
- return [self.delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:section];
- } else {
- return BYHMinimumInterSpacing;
- }
- }
- - (CGFloat)minimumLineWithSection:(NSInteger)section {
- if ([self.delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
- return [self.delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:section];
- } else {
- return BYHMinimumLineSpacing;
- }
- }
- - (UIEdgeInsets)edgeInsetsWithSection:(NSInteger )section {
- if (section < 0) {
- return UIEdgeInsetsZero;
- }
- if ([self.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
- return [self.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
- } else {
- return XHLDefaultEdgeInsets;
- }
- }
- - (CGFloat)headerHeightWithSection:(NSInteger)section {
- if ([self.delegate respondsToSelector:@selector(collectionView:layout:referenceHeightForHeaderInSection:)]) {
- return [self.delegate collectionView:self.collectionView layout:self referenceHeightForHeaderInSection:section];
- }
- return BYHHeaderHeight;
- }
- - (CGFloat)footerHeightWithSection:(NSInteger)section {
- if ([self.delegate respondsToSelector:@selector(collectionView:layout:referenceHeightForFooterInSection:)]) {
- return [self.delegate collectionView:self.collectionView layout:self referenceHeightForFooterInSection:section];
- }
- return BYHFooterHeight;
- }
- /**
- * 初始化
- */
- - (void)prepareLayout
- {
- [super prepareLayout];
-
- self.itemAttrsArray = [NSMutableArray array];
- self.headerAttrsArr = [NSMutableArray array];
- self.footerAttrsArr = [NSMutableArray array];
- CGFloat collectionViewW = self.collectionView.frame.size.width;
-
-
- // 清除之前所有的布局属性
- [self.itemAttrsArray removeAllObjects];
- [self.headerAttrsArr removeAllObjects];
- [self.footerAttrsArr removeAllObjects];
- NSInteger sectionNum = [self.collectionView numberOfSections];
- for (NSInteger section = 0; section < sectionNum; section++) {
-
- UIEdgeInsets sectionInset = [self edgeInsetsWithSection:section];
- CGFloat minimumzLine = [self minimumLineWithSection:section];
- CGFloat minimumzInter = [self minimumInterWithSection:section];
-
- self.itemMaxX = sectionInset.left - minimumzLine;
-
- UICollectionViewLayoutAttributes *headerAttrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
- CGFloat headerHeight = [self headerHeightWithSection:section];
- headerAttrs.frame = CGRectMake(0, self.itemMaxHeight, collectionViewW, headerHeight);
- [self.headerAttrsArr addObject:headerAttrs];
-
- self.itemMaxHeight = self.itemMaxHeight + headerHeight + sectionInset.top;
-
- NSInteger itemNum = [self.collectionView numberOfItemsInSection:section];
- NSMutableArray *sectionItemArr = [NSMutableArray array];
- for (NSInteger item = 0; item < itemNum; item++) {
-
- NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
- CGSize itemSize = [self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
- UICollectionViewLayoutAttributes *itemAttrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
-
- if (itemSize.width >= (collectionViewW - sectionInset.left - sectionInset.right)) {
- if (item != 0) {
- self.itemMaxHeight = self.itemMaxHeight + minimumzInter;
- }
- self.itemMaxX = sectionInset.left;
- itemAttrs.frame = CGRectMake(self.itemMaxX, self.itemMaxHeight, itemSize.width, itemSize.height);
- self.itemMaxHeight = self.itemMaxHeight + itemSize.height + minimumzInter;
- }else {
- if (collectionViewW - self.itemMaxX - sectionInset.right - minimumzLine >= itemSize.width) {
- self.itemMaxX += minimumzLine;
- }else {
- self.itemMaxX = sectionInset.left;
- self.itemMaxHeight = self.itemMaxHeight + minimumzInter + itemSize.height;
- }
- itemAttrs.frame = CGRectMake(self.itemMaxX, self.itemMaxHeight, itemSize.width, itemSize.height);
- self.itemMaxX += itemSize.width;
- }
- if (item == itemNum - 1) {
- self.itemMaxHeight = self.itemMaxHeight + itemSize.height + sectionInset.bottom;
- }
- [sectionItemArr addObject:itemAttrs];
- }
- [self.itemAttrsArray addObject:sectionItemArr];
-
- UICollectionViewLayoutAttributes *footerAttrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter withIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
- CGFloat footerHeight = [self footerHeightWithSection:section];
- [self.footerAttrsArr addObject:footerAttrs];
- footerAttrs.frame = CGRectMake(0, self.itemMaxHeight, collectionViewW, footerHeight);
- self.itemMaxHeight = self.itemMaxHeight + footerHeight;
- self.contentHeight = self.itemMaxHeight;
- }
- }
- /**
- * 决定cell的排布
- */
- - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
- // return self.itemAttrsArray;
-
- NSMutableArray<UICollectionViewLayoutAttributes *> *result = [NSMutableArray array];
- [_itemAttrsArray enumerateObjectsUsingBlock:^(NSMutableArray<UICollectionViewLayoutAttributes *> *layoutAttributeOfSection, NSUInteger idx, BOOL *stop) {
- [layoutAttributeOfSection enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attribute, NSUInteger idx, BOOL *stop) {
- if (CGRectIntersectsRect(rect, attribute.frame)) {
- [result addObject:attribute];
- }
- }];
- }];
- [_headerAttrsArr enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attribute, NSUInteger idx, BOOL *stop) {
- if (attribute.frame.size.height && CGRectIntersectsRect(rect, attribute.frame)) {
- [result addObject:attribute];
- }
- }];
- [_footerAttrsArr enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attribute, NSUInteger idx, BOOL *stop) {
- if (attribute.frame.size.height && CGRectIntersectsRect(rect, attribute.frame)) {
- [result addObject:attribute];
- }
- }];
-
- return result;
- }
- /**
- * 返回indexPath位置cell对应的布局属性
- */
- - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
-
- return self.itemAttrsArray[indexPath.section][indexPath.item];
- }
- - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {
- if ([elementKind isEqualToString:UICollectionElementKindSectionHeader]) {
- NSLog(@"Header: section-%zd, item-%zd", indexPath.section, indexPath.item);
- return self.headerAttrsArr[indexPath.item];
- }
- if ([elementKind isEqualToString:UICollectionElementKindSectionFooter]) {
- NSLog(@"Footer: section-%zd, item-%zd", indexPath.section, indexPath.item);
- return self.footerAttrsArr[indexPath.item];
- }
- return nil;
- }
- - (CGSize)collectionViewContentSize {
- return CGSizeMake(CGRectGetWidth(self.collectionView.bounds), self.contentHeight);
- }
- @end
|