TDHorizontalWaterFlowLayout.m 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. //
  2. // TDHorizontalWaterFlowLayout.m
  3. // TheoryNetwork
  4. //
  5. // Created by tederen on 2019/9/24.
  6. // Copyright © 2019 tederen. All rights reserved.
  7. //
  8. #import "TDHorizontalWaterFlowLayout.h"
  9. #import "ChannelModel.h"
  10. @interface TDHorizontalWaterFlowLayout ()
  11. @property (nonatomic, strong) NSMutableArray *attributesArray; //存放item的属性数组
  12. @property (nonatomic, strong) NSMutableArray *deleteIndexPaths;
  13. @property (nonatomic, strong) NSMutableArray *insertIndexPaths;
  14. @end
  15. @implementation TDHorizontalWaterFlowLayout
  16. //lazy
  17. - (NSMutableArray *)attributesArray {
  18. if (_attributesArray == nil) {
  19. _attributesArray = [[NSMutableArray alloc] init];
  20. }
  21. return _attributesArray;
  22. }
  23. - (void)prepareLayout {
  24. [super prepareLayout];
  25. [self.attributesArray removeAllObjects];
  26. [self computeAttributes];
  27. }
  28. - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
  29. return self.attributesArray;
  30. }
  31. - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
  32. NSInteger count = [self.collectionView numberOfItemsInSection:0];
  33. CGFloat radius = 180;
  34. CGFloat ox = self.collectionView.frame.size.width * 0.5;
  35. CGFloat oy = self.collectionView.frame.size.height * 0.5;
  36. CGFloat angle = 2 * M_PI * indexPath.item / count;
  37. CGFloat centerX = ox + radius*cos(angle);
  38. CGFloat centerY = oy + radius*sin(angle);
  39. UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
  40. attrs.center = CGPointMake(centerX, centerY);
  41. attrs.size = CGSizeMake(kGXScreenWidth / 6, 30);
  42. return attrs;
  43. }
  44. - (NSIndexPath *)targetIndexPathForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath withPosition:(CGPoint)position {
  45. return [self.collectionView indexPathForItemAtPoint:position];
  46. // return [self getPath:position];
  47. // return [NSIndexPath indexPathForRow:9 inSection:0];
  48. }
  49. - (NSIndexPath*)getPath:(CGPoint)position {
  50. for (int i = 0; i < self.attributesArray.count; i++) {
  51. UICollectionViewLayoutAttributes *attr = [self.attributesArray objectAtIndex:i];
  52. if (CGRectContainsPoint(attr.frame, position)) {
  53. return attr.indexPath;
  54. }
  55. }
  56. return nil;
  57. }
  58. - (CGSize)collectionViewContentSize {
  59. return CGSizeMake(kGXScreenWidth / 6, 30);
  60. }
  61. - (void)prepareForCollectionViewUpdates:(NSArray *)updateItems {
  62. [super prepareForCollectionViewUpdates:updateItems];
  63. self.deleteIndexPaths = @[].mutableCopy;
  64. self.insertIndexPaths = @[].mutableCopy;
  65. for (UICollectionViewUpdateItem *update in updateItems) {
  66. if (update.updateAction == UICollectionUpdateActionDelete) {
  67. [self.deleteIndexPaths addObject:update.indexPathBeforeUpdate];
  68. }else if (update.updateAction == UICollectionUpdateActionInsert) {
  69. [self.insertIndexPaths addObject:update.indexPathAfterUpdate];
  70. }
  71. }
  72. }
  73. - (void)finalizeCollectionViewUpdates {
  74. [super finalizeCollectionViewUpdates];
  75. [self.deleteIndexPaths removeAllObjects];
  76. [self.insertIndexPaths removeAllObjects];
  77. }
  78. //计算每个单元格的属性
  79. - (void)computeAttributes {
  80. //存贮每行个数
  81. NSMutableArray *lineNum = [[NSMutableArray alloc] init];
  82. [lineNum insertObject:@0 atIndex:0];
  83. //储存每行宽度
  84. NSMutableArray *lineWidth = [[NSMutableArray alloc] init];
  85. [lineWidth insertObject:@10.0 atIndex:0];
  86. //当前添加的行号
  87. int index = 0;
  88. //记录当前高度
  89. CGFloat verticalHeight = 0;
  90. CGFloat cellHeight = 42;
  91. CGFloat headerHeight = 40;
  92. CGFloat cellSpaceH = 10;
  93. CGFloat cellSpaceV = 13;
  94. CGFloat topMarginHeader = 0; // header 的 top
  95. CGFloat topMarginCell = 0; // cell 的 top
  96. for (int k = 0; k < self.dataList.count; k ++) {
  97. NSArray *array = self.dataList[k];
  98. //添加一个组头
  99. if (k == 0) {
  100. topMarginHeader = headerHeight * k + index * cellHeight + index * cellSpaceV;
  101. }else{
  102. topMarginHeader = headerHeight * k + (index-1) * cellHeight + (index-1) * cellSpaceV;
  103. }
  104. UICollectionViewLayoutAttributes *headerAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathForItem:0 inSection:k]];
  105. headerAttributes .frame = CGRectMake(0, topMarginHeader, kGXScreenWidth, headerHeight);
  106. [self.attributesArray addObject:headerAttributes];
  107. //相当于添加了一行
  108. [lineNum addObject:@1];
  109. [lineWidth addObject:@(kGXScreenWidth)];
  110. //添加组头,不需要计算组头的高度,单元格会自动适配到组头下面
  111. index ++;
  112. CGFloat X ;
  113. topMarginCell += topMarginHeader + headerHeight - 15;
  114. CGFloat Y = topMarginCell;
  115. for (int i = 0; i < array.count; i ++) {
  116. UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:k]];
  117. //计算宽度
  118. CGFloat width = 80;
  119. ChannelModel *model = array[i];
  120. if (model.Name.length <= 4) {}
  121. else{
  122. width = [self computerWidthWithString:model.Name];
  123. }
  124. //计算位置
  125. // CGFloat X ;
  126. // CGFloat Y = topMarginCell;
  127. CGFloat indexWidth = [lineWidth[index] floatValue]; //当前行宽
  128. if ((indexWidth + width + cellSpaceH) <= self.collectionView.bounds.size.width) {
  129. //如果添加一个单元格,此行宽度还小于控件宽度,那就添加到此行
  130. X = [lineWidth[index] floatValue];
  131. Y = topMarginCell ;
  132. lineNum[index] = @([lineNum[index] intValue] + 1);
  133. lineWidth[index] = @([lineWidth[index] floatValue] + width + cellSpaceH);
  134. }else{
  135. //如果添加一个单元格,此行宽度大于控件宽度,那就另起一行
  136. index ++;
  137. topMarginCell += cellHeight + cellSpaceV;
  138. Y = topMarginCell;
  139. X = 12;
  140. [lineNum addObject:@(1)];
  141. [lineWidth addObject:@(width + cellSpaceH + cellSpaceH)];
  142. }
  143. attributes.frame = CGRectMake(X, Y-headerHeight, width, cellHeight);
  144. [self.attributesArray addObject:attributes];
  145. self.itemSize = CGSizeMake(width, cellHeight);
  146. }
  147. topMarginCell = 0;
  148. // // for (int i = 0; i < array.count; i ++) {
  149. // UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:k]];
  150. // //计算宽度
  151. // CGFloat width = 80;
  152. // ChannelModel *model = array[i];
  153. // if (model.channelName.length <= 4) {}
  154. // else{
  155. // width = [self computerWidthWithString:model.channelName];
  156. // }
  157. // //计算位置
  158. // CGFloat X ;
  159. // CGFloat Y = topMarginCell;
  160. // CGFloat indexWidth = [lineWidth[index] floatValue]; //当前行宽
  161. // if ((indexWidth + width + cellSpaceH) <= self.collectionView.bounds.size.width) {
  162. // //如果添加一个单元格,此行宽度还小于控件宽度,那就添加到此行
  163. // X = [lineWidth[index] floatValue];
  164. // Y = verticalHeight;
  165. // lineNum[index] = @([lineNum[index] intValue] + 1);
  166. // lineWidth[index] = @([lineWidth[index] floatValue] + width + cellSpaceH);
  167. // }else{
  168. // //如果添加一个单元格,此行宽度大于控件宽度,那就另起一行
  169. // index ++;
  170. // verticalHeight += cellHeight + cellSpaceV;
  171. // Y = verticalHeight;
  172. // X = cellSpaceH;
  173. // [lineNum addObject:@(1)];
  174. // [lineWidth addObject:@(width + cellSpaceH + cellSpaceH)];
  175. // }
  176. // attributes.frame = CGRectMake(X, Y-headerHeight, width, cellHeight);
  177. // [self.attributesArray addObject:attributes];
  178. // self.itemSize = CGSizeMake(width, cellHeight);
  179. //
  180. // }
  181. }
  182. }
  183. //计算单元格宽度
  184. - (CGFloat)computerWidthWithString:(NSString *)string {
  185. CGRect rect = [string boundingRectWithSize:CGSizeMake(1000, 9999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil];
  186. return rect.size.width + 20;
  187. }
  188. ////计算最宽行
  189. //- (int)computerMAXlineWithArray:(NSArray *)array {
  190. // int maxIndex = 0;
  191. // CGFloat maxfloat = 0;
  192. // for (int i=0; i<array.count; i++) {
  193. // CGFloat ifloat = [array[i] floatValue];
  194. // if (ifloat > maxfloat) {
  195. // maxIndex = i;
  196. // maxfloat = ifloat;
  197. // }
  198. // }
  199. // return maxIndex;
  200. //}
  201. @end