实现效果
1.控制器的实现
#import "ViewController.h"
#import "PhotoCell.h"
#import "PhotoFlowLayout.h"
@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
@end
static NSString* identifier = @"photoCell";
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
PhotoFlowLayout *flowLayout = [[PhotoFlowLayout alloc]init];
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 200, self.view.frame.size.width, 300) collectionViewLayout:flowLayout];
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.backgroundColor = [UIColor darkGrayColor];
collectionView.showsHorizontalScrollIndicator = NO;
[collectionView registerClass:[PhotoCell class] forCellWithReuseIdentifier:identifier];
[self.view addSubview:collectionView];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 20;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor blueColor];
return cell;
}
@end
2.自定义cell
#import "PhotoCell.h"
@implementation PhotoCell
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
UIView *view = [[UIView alloc]initWithFrame:self.contentView.bounds];
UIColor *color = [UIColor colorWithRed: arc4random_uniform(255)/255.0 green: arc4random_uniform(255)/255.0 blue: arc4random_uniform(255)/255.0 alpha:1.0];
view.backgroundColor = color;
[self.contentView addSubview:view];
}
return self;
}
@end
3. 自定义flowlayout
#import "PhotoFlowLayout.h"
@implementation PhotoFlowLayout
-(void)prepareLayout{
[super prepareLayout];
CGSize collectionViewSize = self.collectionView.frame.size;
CGFloat itemWidth = collectionViewSize.height * 0.6;
CGFloat itemHeight = collectionViewSize.height * 0.8;
self.itemSize = CGSizeMake(itemWidth, itemHeight);
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
// 设置头部和尾部的初始间距
CGFloat margin = collectionViewSize.width/2 - itemWidth/2;
self.sectionInset = UIEdgeInsetsMake(0, margin, 0, margin);
}
//当屏幕的可见范围发生变化的时候, 要重新刷新布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
// 当手指离开collectionView的时候会调用 让view 在中间显示
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
//屏幕的中心点
CGFloat screenCenter = proposedContentOffset.x + self.collectionView.frame.size.width/2;
//取出可见范围内的cell
CGRect visibleRect = CGRectZero;
visibleRect.size = self.collectionView.frame.size;
visibleRect.origin = proposedContentOffset;
//获取可见范围内的cell属性集合 调用super 的方法, 是避免重新计算比率
NSArray *visibleArray = [super layoutAttributesForElementsInRect:visibleRect];
// 定义最小的 间距
CGFloat minMargin = MAXFLOAT;
for (UICollectionViewLayoutAttributes *attributes in visibleArray) {
// 计算cell的中心点 和 屏幕中心点的差值
CGFloat deltaMargin = attributes.center.x - screenCenter;
if (fabs(minMargin) > fabs(deltaMargin)) {
minMargin = deltaMargin;
}
}
return CGPointMake(proposedContentOffset.x + minMargin, proposedContentOffset.y);
}
// 所有可见范围 itemcell 属性,一个UICollectionViewLayoutAttributes对应一个itemcell
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
NSArray *superAttributes = [super layoutAttributesForElementsInRect:rect];
CGFloat screenCenter = self.collectionView.contentOffset.x + self.collectionView.frame.size.width/2;
[superAttributes enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UICollectionViewLayoutAttributes * attrs = obj;
// 小 就是离屏幕中心近
CGFloat deltaMargin = fabs(screenCenter - attrs.center.x);
// 离屏幕中心近 放大点
CGFloat scaleDelta = 1.1 - deltaMargin / (self.collectionView.frame.size.width/2 + attrs.size.width);
attrs.transform = CGAffineTransformMakeScale(scaleDelta, scaleDelta);
}];
return superAttributes;
}
@end