自定义UICollectionViewFlowLayout

来源:互联网 发布:网络用语jqk什么意思 编辑:程序博客网 时间:2024/06/01 22:51

这里写图片描述

系统给我们一个线性布局FlowLayout,但是满足不了我们的需求,所以需要自定义一个FlowLayout(可以继承FloaLayout,也可以继承layout),这里我继承了FlowLayout

#import <UIKit/UIKit.h>@interface KSCollectionViewFlowLayout : UICollectionViewFlowLayout@end

下面我们需要重写里面的三个方法

//这个方法可以设置cell落在中间的位置/** *  返回一个Point,让collectionView 停在这个点上 *  @param proposedContentOffset collectionView 系统预计要停止的点 *  @param velocity              速度 */- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity;
/** *  @param rect 当前collctionView展示的区域 *  @return 返回一个UICollectionViewLayoutAttributes数组,详情查看UICollectionViewLayoutAttributes各种属性 */ - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
//返回YES 当CollectionView只要滚动就调用上面两个方法,默认返回NO,在适当的时候调用上面两个方法- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;

具体实现方法

实现这个方法能使滚动停止后始终让item落在中间位置

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{    //1.首先拿到预计滚动停止后展示的item  [super layoutAttributesForElementsInRect:rect]    CGRect rect = CGRectMake(proposedContentOffset.x, proposedContentOffset.y, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);    NSArray* attArray = [super layoutAttributesForElementsInRect:rect];    //2.找到距离中间最近的item    CGFloat minMargin = MAXFLOAT;    for (UICollectionViewLayoutAttributes* att in attArray) {       CGFloat margin = att.center.x - proposedContentOffset.x - self.collectionView.bounds.size.width * 0.5;        if (ABS(minMargin) > ABS(margin)) {            minMargin = margin;        }    }    //3.修改collectionView预计滚动的位置,正巧落在中间item的上面    proposedContentOffset.x += minMargin;    return proposedContentOffset;}

实现这个方法能改变item的缩放效果

- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{    //1.首先拿到预计滚动停止后展示的item  [super layoutAttributesForElementsInRect:rect]    NSArray* attArray = [super layoutAttributesForElementsInRect:rect];    for (UICollectionViewLayoutAttributes* att in attArray) {        //2.遍历各个item,根据位置来改变缩放效果        CGFloat distance = att.center.x - self.collectionView.contentOffset.x - self.collectionView.bounds.size.width * 0.5;        CGFloat scale = 1- ABS(distance) / self.collectionView.bounds.size.width;        att.transform = CGAffineTransformMakeScale(scale, scale);    }    //返回item    return  attArray;}

实现这个方法,只要滚动就调用上面两个方法,实时更新

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{    return YES;}
0 0