YOUPAIWZHorizontalPageFlowlayout.m 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //
  2. // YOUPAIWZHorizontalPageFlowlayout.m
  3. // WZShenmaStar
  4. //
  5. // Created by bigbiao on 2017/5/10.
  6. // Copyright © 2017年 BigBiao. All rights reserved.
  7. //
  8. #import "YOUPAIWZHorizontalPageFlowlayout.h"
  9. @implementation YOUPAIWZHorizontalPageFlowlayout
  10. #pragma mark - Public
  11. - (void)setColumnSpacing:(CGFloat)columnSpacing rowSpacing:(CGFloat)rowSpacing edgeInsets:(UIEdgeInsets)edgeInsets
  12. {
  13. self.youpaipcolumnSpacing = columnSpacing;
  14. self.youpaiprowSpacing = rowSpacing;
  15. self.youpaipedgeInsets = edgeInsets;
  16. }
  17. - (void)setRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow
  18. {
  19. self.youpaiprowCount = rowCount;
  20. self.youpaipitemCountPerRow = itemCountPerRow;
  21. }
  22. #pragma mark - 构造方法
  23. + (instancetype)youpaifhorizontalPageFlowlayoutWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow
  24. {
  25. return [[self alloc] initWithRowCount:rowCount itemCountPerRow:itemCountPerRow];
  26. }
  27. - (instancetype)initWithRowCount:(NSInteger)rowCount itemCountPerRow:(NSInteger)itemCountPerRow
  28. {
  29. self = [super init];
  30. if (self) {
  31. self.youpaiprowCount = rowCount;
  32. self.youpaipitemCountPerRow = itemCountPerRow;
  33. }
  34. return self;
  35. }
  36. #pragma mark - 重写父类方法
  37. - (instancetype)init
  38. {
  39. self = [super init];
  40. if (self) {
  41. [self setColumnSpacing:0 rowSpacing:0 edgeInsets:UIEdgeInsetsZero];
  42. }
  43. return self;
  44. }
  45. /** 布局前做一些准备工作 */
  46. - (void)prepareLayout
  47. {
  48. [super prepareLayout];
  49. // 从collectionView中获取到有多少个item
  50. NSInteger itemTotalCount = [self.collectionView numberOfItemsInSection:0];
  51. // 遍历出item的attributes,把它添加到管理它的属性数组中去
  52. for (int i = 0; i < itemTotalCount; i++) {
  53. NSIndexPath *indexpath = [NSIndexPath indexPathForItem:i inSection:0];
  54. UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexpath];
  55. [self.youpaipattributesArrayM addObject:attributes];
  56. }
  57. }
  58. /** 计算collectionView的滚动范围 */
  59. - (CGSize)collectionViewContentSize
  60. {
  61. // 计算出item的宽度
  62. CGFloat itemWidth = (self.collectionView.frame.size.width - self.youpaipedgeInsets.left - self.youpaipitemCountPerRow * self.youpaipcolumnSpacing) / self.youpaipitemCountPerRow;
  63. // 从collectionView中获取到有多少个item
  64. NSInteger itemTotalCount = [self.collectionView numberOfItemsInSection:0];
  65. // 理论上每页展示的item数目
  66. NSInteger itemCount = self.youpaiprowCount * self.youpaipitemCountPerRow;
  67. // 余数(用于确定最后一页展示的item个数)
  68. NSInteger remainder = itemTotalCount % itemCount;
  69. // 除数(用于判断页数)
  70. NSInteger pageNumber = itemTotalCount / itemCount;
  71. // 总个数小于self.rowCount * self.itemCountPerRow
  72. if (itemTotalCount <= itemCount) {
  73. pageNumber = 1;
  74. }else {
  75. if (remainder == 0) {
  76. pageNumber = pageNumber;
  77. }else {
  78. // 余数不为0,除数加1
  79. pageNumber = pageNumber + 1;
  80. }
  81. }
  82. CGFloat width = 0;
  83. // 考虑特殊情况(当item的总个数不是self.rowCount * self.itemCountPerRow的整数倍,并且余数小于每行展示的个数的时候)
  84. // if (pageNumber > 1 && remainder != 0 && remainder < self.itemCountPerRow) {
  85. // width = self.edgeInsets.left + (pageNumber - 1) * self.itemCountPerRow * (itemWidth + self.columnSpacing) + remainder * itemWidth + (remainder - 1)*self.columnSpacing + self.edgeInsets.right;
  86. // }else {
  87. width = self.youpaipedgeInsets.left + pageNumber * self.youpaipitemCountPerRow * (itemWidth + self.youpaipcolumnSpacing) - self.youpaipcolumnSpacing + self.youpaipedgeInsets.right;
  88. // }
  89. // 只支持水平方向上的滚动
  90. return CGSizeMake(width, 0);
  91. }
  92. /** 设置每个item的属性(主要是frame) */
  93. - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
  94. {
  95. // item的宽高由行列间距和collectionView的内边距决定
  96. CGFloat itemWidth = (self.collectionView.frame.size.width - self.youpaipedgeInsets.left - self.youpaipitemCountPerRow * self.youpaipcolumnSpacing) / self.youpaipitemCountPerRow;
  97. CGFloat itemHeight = (self.collectionView.frame.size.height - self.youpaipedgeInsets.top - self.youpaipedgeInsets.bottom - (self.youpaiprowCount - 1) * self.youpaiprowSpacing) / self.youpaiprowCount;
  98. NSInteger item = indexPath.item;
  99. // 当前item所在的页
  100. NSInteger pageNumber = item / (self.youpaiprowCount * self.youpaipitemCountPerRow);
  101. NSInteger x = item % self.youpaipitemCountPerRow + pageNumber * self.youpaipitemCountPerRow;
  102. NSInteger y = item / self.youpaipitemCountPerRow - pageNumber * self.youpaiprowCount;
  103. // 计算出item的坐标
  104. CGFloat itemX = self.youpaipedgeInsets.left + (itemWidth + self.youpaipcolumnSpacing) * x;
  105. CGFloat itemY = self.youpaipedgeInsets.top + (itemHeight + self.youpaiprowSpacing) * y;
  106. UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
  107. // 每个item的frame
  108. attributes.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);
  109. return attributes;
  110. }
  111. /** 返回collectionView视图中所有视图的属性数组 */
  112. - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
  113. {
  114. return self.youpaipattributesArrayM;
  115. }
  116. #pragma mark - Lazy
  117. - (NSMutableArray *)youpaipattributesArrayM
  118. {
  119. if (!_youpaipattributesArrayM) {
  120. _youpaipattributesArrayM = [NSMutableArray array];
  121. }
  122. return _youpaipattributesArrayM;
  123. }
  124. @end