123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- //
- // 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<array.count; i++) {
- // CGFloat ifloat = [array[i] floatValue];
- // if (ifloat > maxfloat) {
- // maxIndex = i;
- // maxfloat = ifloat;
- // }
- // }
- // return maxIndex;
- //}
- @end
|