重写prepareLayout方法
- 作用:在这个方法中做一些初始化操作
- 注意:一定要调用[super prepareLayout]
重写layoutAttributesForElementsInRect:方法
- 作用:
- 这个方法的返回值是个数组
- 这个数组中存放的都是UICollectionViewLayoutAttributes对象
- UICollectionViewLayoutAttributes对象决定了cell的排布方式(frame等)
重写shouldInvalidateLayoutForBoundsChange:方法
- 作用:如果返回YES,那么collectionView显示的范围发生改变时,就会重新刷新布局
- 一旦重新刷新布局,就会按顺序调用下面的方法:
- prepareLayout
- layoutAttributesForElementsInRect:
重写targetContentOffsetForProposedContentOffset:withScrollingVelocity:方法
- 作用:返回值决定了collectionView停止滚动时最终的偏移量(contentOffset)
- 参数:
- proposedContentOffset:原本情况下,collectionView停止滚动时最终的偏移量
- velocity:滚动速率,通过这个参数可以了解滚动的方向
示例展示
/**
* 准备布局
*/
- (void)prepareLayout {
[super prepareLayout];
self.itemSize = CGSizeMake(200, 200);
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
//设置起始的内边距
CGFloat inset = (self.collectionView.frame.size.width - self.itemSize.width) * 0.5;
self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
}
/**
* 用来刷新重新布局
*/
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
/**
* 用来布局cell的frame
*/
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attrsArray = [super layoutAttributesForElementsInRect:rect];
//获取到collectionView的中心点的X
CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
for (UICollectionViewLayoutAttributes *attr in attrsArray) {
CGFloat delta = ABS(attr.center.x - centerX);
CGFloat scale = 1 - delta / self.collectionView.frame.size.width;
attr.transform = CGAffineTransformMakeScale(scale, scale);
}
return attrsArray;
}
/**
* 用来布局cell最终的落点
*/
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
CGRect rect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.frame.size.width, self.collectionView.frame.size.height);
//获取到cell的frame
NSArray *attrsArray = [super layoutAttributesForElementsInRect:rect];
CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
//计算cellectionView中心点最小的值
CGFloat minDetla = CGFLOAT_MAX;
for (UICollectionViewLayoutAttributes *attr in attrsArray) {
if (ABS(minDetla) > ABS(centerX - attr.center.x)) {
minDetla = attr.center.x - centerX;
}
}
proposedContentOffset.x += minDetla;
return proposedContentOffset;
}
github:https://github.com/aryehToDog/WK-collectionView