一分钟学会collectionView自定义layout(一)

时间:2022-01-16 21:19:06

第一步:
继承自UICollectionViewFlowLayout
再写prepareLayout

-(void)prepareLayout{

//item的大小
// self.itemSize = CGSizeMake(50, 50);
//滑动方向
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

//设置内容视图的四周间距
CGFloat insert = (self.collectionView.frame.size.width - self.itemSize.width)/2;
self.sectionInset = UIEdgeInsetsMake(0, insert, 0, insert);

//设置行间距
self.minimumLineSpacing = 50.0;

}

第二步:设置停止滚动时的偏移量

//停止滚动时调用,返回值确定collectionView的偏移量
//proposedContentOffset 是默认的偏移量
//velocity是滚动的速度,值的正负代表方向
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
//计算出 最终显示的矩形框
CGRect rect;
rect.origin.x =proposedContentOffset.x;
rect.origin.y=0;
rect.size=self.collectionView.frame.size;

NSArray * array = [super layoutAttributesForElementsInRect:rect];

// 计算CollectionView最中心点的x值 这里要求 最终的 要考虑惯性
CGFloat centerX = self.collectionView.frame.size.width /2+ proposedContentOffset.x;
//存放的最小间距
CGFloat minDelta = MAXFLOAT;
for (UICollectionViewLayoutAttributes * attrs in array) {
if (ABS(minDelta)>ABS(attrs.center.x-centerX)) {
minDelta=attrs.center.x-centerX;
}
}
// 修改原有的偏移量
proposedContentOffset.x+=minDelta;
//如果返回的时zero 那个滑动停止后 就会立刻回到原地
return proposedContentOffset;
}

第三步:
每个item的大小

//返回数组,Attributes是每个item的布局元素(包含frame、size等)
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
SArray * array = [super layoutAttributesForElementsInRect:rect];
//计算CollectionView最中心的x
#warning 特别注意:
CGFloat centetX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width/2;

for (UICollectionViewLayoutAttributes * attrs in array) {
//CGFloat scale = arc4random_uniform(100)/100.0;
//attrs.indexPath.item 表示 这个attrs对应的cell的位置
NSLog(@" 第%zdcell--距离:%.1f",attrs.indexPath.item ,attrs.center.x - centetX);
//cell的中心点x 和CollectionView最中心点的x
CGFloat delta = ABS(attrs.center.x - centetX);
//根据间距值 计算cell的缩放的比例
//这里scale 必须要 小于1
CGFloat scale = 1 - delta/self.collectionView.frame.size.width;
//设置缩放比例
attrs.transform=CGAffineTransformMakeScale(scale, scale);
}
return array;
}

最后:

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

运行后如图:
一分钟学会collectionView自定义layout(一)