// // TDHorizontalWaterFlowLayout.m // TheoryNetwork // // Created by tederen on 2019/9/24. // Copyright © 2019 tederen. All rights reserved. // #import "TDHorizontalWaterFlowLayout.h" #import "ChannelModel.h" @interface TDHorizontalWaterFlowLayout () @property (nonatomic, strong) NSMutableArray *attributesArray; //存放item的属性数组 @property (nonatomic, strong) NSMutableArray *deleteIndexPaths; @property (nonatomic, strong) NSMutableArray *insertIndexPaths; @end @implementation TDHorizontalWaterFlowLayout //lazy - (NSMutableArray *)attributesArray { if (_attributesArray == nil) { _attributesArray = [[NSMutableArray alloc] init]; } return _attributesArray; } - (void)prepareLayout { [super prepareLayout]; [self.attributesArray removeAllObjects]; [self computeAttributes]; } - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { return self.attributesArray; } - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { NSInteger count = [self.collectionView numberOfItemsInSection:0]; CGFloat radius = 180; CGFloat ox = self.collectionView.frame.size.width * 0.5; CGFloat oy = self.collectionView.frame.size.height * 0.5; CGFloat angle = 2 * M_PI * indexPath.item / count; CGFloat centerX = ox + radius*cos(angle); CGFloat centerY = oy + radius*sin(angle); UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; attrs.center = CGPointMake(centerX, centerY); attrs.size = CGSizeMake(kGXScreenWidth / 6, 30); return attrs; } - (NSIndexPath *)targetIndexPathForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath withPosition:(CGPoint)position { return [self.collectionView indexPathForItemAtPoint:position]; // return [self getPath:position]; // return [NSIndexPath indexPathForRow:9 inSection:0]; } - (NSIndexPath*)getPath:(CGPoint)position { for (int i = 0; i < self.attributesArray.count; i++) { UICollectionViewLayoutAttributes *attr = [self.attributesArray objectAtIndex:i]; if (CGRectContainsPoint(attr.frame, position)) { return attr.indexPath; } } return nil; } - (CGSize)collectionViewContentSize { return CGSizeMake(kGXScreenWidth / 6, 30); } - (void)prepareForCollectionViewUpdates:(NSArray *)updateItems { [super prepareForCollectionViewUpdates:updateItems]; self.deleteIndexPaths = @[].mutableCopy; self.insertIndexPaths = @[].mutableCopy; for (UICollectionViewUpdateItem *update in updateItems) { if (update.updateAction == UICollectionUpdateActionDelete) { [self.deleteIndexPaths addObject:update.indexPathBeforeUpdate]; }else if (update.updateAction == UICollectionUpdateActionInsert) { [self.insertIndexPaths addObject:update.indexPathAfterUpdate]; } } } - (void)finalizeCollectionViewUpdates { [super finalizeCollectionViewUpdates]; [self.deleteIndexPaths removeAllObjects]; [self.insertIndexPaths removeAllObjects]; } //计算每个单元格的属性 - (void)computeAttributes { //存贮每行个数 NSMutableArray *lineNum = [[NSMutableArray alloc] init]; [lineNum insertObject:@0 atIndex:0]; //储存每行宽度 NSMutableArray *lineWidth = [[NSMutableArray alloc] init]; [lineWidth insertObject:@10.0 atIndex:0]; //当前添加的行号 int index = 0; //记录当前高度 CGFloat verticalHeight = 0; CGFloat cellHeight = 42; CGFloat headerHeight = 40; CGFloat cellSpaceH = 10; CGFloat cellSpaceV = 13; CGFloat topMarginHeader = 0; // header 的 top CGFloat topMarginCell = 0; // cell 的 top for (int k = 0; k < self.dataList.count; k ++) { NSArray *array = self.dataList[k]; //添加一个组头 if (k == 0) { topMarginHeader = headerHeight * k + index * cellHeight + index * cellSpaceV; }else{ topMarginHeader = headerHeight * k + (index-1) * cellHeight + (index-1) * cellSpaceV; } UICollectionViewLayoutAttributes *headerAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathForItem:0 inSection:k]]; headerAttributes .frame = CGRectMake(0, topMarginHeader, kGXScreenWidth, headerHeight); [self.attributesArray addObject:headerAttributes]; //相当于添加了一行 [lineNum addObject:@1]; [lineWidth addObject:@(kGXScreenWidth)]; //添加组头,不需要计算组头的高度,单元格会自动适配到组头下面 index ++; CGFloat X ; topMarginCell += topMarginHeader + headerHeight - 15; CGFloat Y = topMarginCell; for (int i = 0; i < array.count; i ++) { UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:k]]; //计算宽度 CGFloat width = 80; ChannelModel *model = array[i]; if (model.Name.length <= 4) {} else{ width = [self computerWidthWithString:model.Name]; } //计算位置 // CGFloat X ; // CGFloat Y = topMarginCell; CGFloat indexWidth = [lineWidth[index] floatValue]; //当前行宽 if ((indexWidth + width + cellSpaceH) <= self.collectionView.bounds.size.width) { //如果添加一个单元格,此行宽度还小于控件宽度,那就添加到此行 X = [lineWidth[index] floatValue]; Y = topMarginCell ; lineNum[index] = @([lineNum[index] intValue] + 1); lineWidth[index] = @([lineWidth[index] floatValue] + width + cellSpaceH); }else{ //如果添加一个单元格,此行宽度大于控件宽度,那就另起一行 index ++; topMarginCell += cellHeight + cellSpaceV; Y = topMarginCell; X = 12; [lineNum addObject:@(1)]; [lineWidth addObject:@(width + cellSpaceH + cellSpaceH)]; } attributes.frame = CGRectMake(X, Y-headerHeight, width, cellHeight); [self.attributesArray addObject:attributes]; self.itemSize = CGSizeMake(width, cellHeight); } topMarginCell = 0; // // for (int i = 0; i < array.count; i ++) { // UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:k]]; // //计算宽度 // CGFloat width = 80; // ChannelModel *model = array[i]; // if (model.channelName.length <= 4) {} // else{ // width = [self computerWidthWithString:model.channelName]; // } // //计算位置 // CGFloat X ; // CGFloat Y = topMarginCell; // CGFloat indexWidth = [lineWidth[index] floatValue]; //当前行宽 // if ((indexWidth + width + cellSpaceH) <= self.collectionView.bounds.size.width) { // //如果添加一个单元格,此行宽度还小于控件宽度,那就添加到此行 // X = [lineWidth[index] floatValue]; // Y = verticalHeight; // lineNum[index] = @([lineNum[index] intValue] + 1); // lineWidth[index] = @([lineWidth[index] floatValue] + width + cellSpaceH); // }else{ // //如果添加一个单元格,此行宽度大于控件宽度,那就另起一行 // index ++; // verticalHeight += cellHeight + cellSpaceV; // Y = verticalHeight; // X = cellSpaceH; // [lineNum addObject:@(1)]; // [lineWidth addObject:@(width + cellSpaceH + cellSpaceH)]; // } // attributes.frame = CGRectMake(X, Y-headerHeight, width, cellHeight); // [self.attributesArray addObject:attributes]; // self.itemSize = CGSizeMake(width, cellHeight); // // } } } //计算单元格宽度 - (CGFloat)computerWidthWithString:(NSString *)string { CGRect rect = [string boundingRectWithSize:CGSizeMake(1000, 9999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil]; return rect.size.width + 20; } ////计算最宽行 //- (int)computerMAXlineWithArray:(NSArray *)array { // int maxIndex = 0; // CGFloat maxfloat = 0; // for (int i=0; i maxfloat) { // maxIndex = i; // maxfloat = ifloat; // } // } // return maxIndex; //} @end