RDSCollectionViewFlowLayout.m 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //
  2. // RDSCollectionViewFlowLayout.m
  3. // LampRibbon
  4. //
  5. // Created by coderYK on 2017/8/9.
  6. // Copyright © 2017年 RD-iOS. All rights reserved.
  7. //
  8. #import "RDSCollectionViewFlowLayout.h"
  9. @implementation RDSCollectionViewFlowLayout
  10. //设置 cell 布局
  11. //返回一定范围内的 cell 的布局
  12. //可以一次性返回全部的 cell
  13. //返回的数组是 cell 的布局信息
  14. - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
  15. {
  16. /*
  17. 实现思路:在指定 rect 中,距离中心点越近的 cell 缩放比例越大,越远的,缩放比例越小
  18. 实时距离 -> 缩放比例
  19. */
  20. NSArray *attrs = [self getCopyOfAttributes:[super layoutAttributesForElementsInRect: self.collectionView.bounds]];
  21. CGFloat distance;
  22. CGFloat scale;
  23. for (UICollectionViewLayoutAttributes *attr in attrs) {
  24. distance = attr.center.x - (self.collectionView.contentOffset.x + SCREEN_WIDTH * 0.5);
  25. scale = 1 - fabs(distance) / SCREEN_WIDTH * 0.5;
  26. attr.transform = CGAffineTransformMakeScale(scale, scale);
  27. }
  28. return attrs;
  29. }
  30. - (NSArray *)getCopyOfAttributes:(NSArray *)attributes {
  31. NSMutableArray *copyArr = [NSMutableArray new];
  32. for (UICollectionViewLayoutAttributes *attribute in attributes) {
  33. [copyArr addObject:[attribute copy]];
  34. }
  35. return copyArr;
  36. }
  37. //作用:决定UICollectionView最终偏移量
  38. //什么时候调用:只要当用户停止拖动时才调用
  39. //可以在这个方法中定位 cell
  40. - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
  41. {
  42. //获得最终的显示区域
  43. CGRect targetR = CGRectMake(proposedContentOffset.x, 0, SCREEN_WIDTH, MAXFLOAT);
  44. NSArray *attrs = [super layoutAttributesForElementsInRect:targetR];
  45. //对距离中心点最近的 cell平移
  46. CGFloat minDistance = MAXFLOAT;
  47. CGFloat distance;
  48. for (UICollectionViewLayoutAttributes *attr in attrs) {
  49. distance = attr.center.x - (proposedContentOffset.x + SCREEN_WIDTH * 0.5);
  50. if (fabs(distance) < fabs(minDistance)) {
  51. minDistance = distance;
  52. }
  53. }
  54. proposedContentOffset.x += minDistance;
  55. if (proposedContentOffset.x < 0) {
  56. proposedContentOffset.x = 0;
  57. }
  58. /*
  59. 快速拖动: 最终偏移量 != 手指离开时的偏移量
  60. */
  61. return proposedContentOffset;
  62. }
  63. //Invalidate:刷新
  64. //是否允许刷新布局,当内容改变的时候
  65. - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
  66. {
  67. return YES;
  68. }
  69. @end