// // RDSCollectionViewFlowLayout.m // LampRibbon // // Created by coderYK on 2017/8/9. // Copyright © 2017年 RD-iOS. All rights reserved. // #import "RDSCollectionViewFlowLayout.h" @implementation RDSCollectionViewFlowLayout //设置 cell 布局 //返回一定范围内的 cell 的布局 //可以一次性返回全部的 cell //返回的数组是 cell 的布局信息 - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { /* 实现思路:在指定 rect 中,距离中心点越近的 cell 缩放比例越大,越远的,缩放比例越小 实时距离 -> 缩放比例 */ NSArray *attrs = [self getCopyOfAttributes:[super layoutAttributesForElementsInRect: self.collectionView.bounds]]; CGFloat distance; CGFloat scale; for (UICollectionViewLayoutAttributes *attr in attrs) { distance = attr.center.x - (self.collectionView.contentOffset.x + SCREEN_WIDTH * 0.5); scale = 1 - fabs(distance) / SCREEN_WIDTH * 0.5; attr.transform = CGAffineTransformMakeScale(scale, scale); } return attrs; } - (NSArray *)getCopyOfAttributes:(NSArray *)attributes { NSMutableArray *copyArr = [NSMutableArray new]; for (UICollectionViewLayoutAttributes *attribute in attributes) { [copyArr addObject:[attribute copy]]; } return copyArr; } //作用:决定UICollectionView最终偏移量 //什么时候调用:只要当用户停止拖动时才调用 //可以在这个方法中定位 cell - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { //获得最终的显示区域 CGRect targetR = CGRectMake(proposedContentOffset.x, 0, SCREEN_WIDTH, MAXFLOAT); NSArray *attrs = [super layoutAttributesForElementsInRect:targetR]; //对距离中心点最近的 cell平移 CGFloat minDistance = MAXFLOAT; CGFloat distance; for (UICollectionViewLayoutAttributes *attr in attrs) { distance = attr.center.x - (proposedContentOffset.x + SCREEN_WIDTH * 0.5); if (fabs(distance) < fabs(minDistance)) { minDistance = distance; } } proposedContentOffset.x += minDistance; if (proposedContentOffset.x < 0) { proposedContentOffset.x = 0; } /* 快速拖动: 最终偏移量 != 手指离开时的偏移量 */ return proposedContentOffset; } //Invalidate:刷新 //是否允许刷新布局,当内容改变的时候 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } @end