collectionView 是在iOS中经常使用的一个类,有时候经常会遇到一些奇葩的需求,要求item可以按照需求随意摆放,这时候就需要重写几个类来实现了。废话少说,上代码。
重写布局类UICollectionViewFlowLayout 或者UICollectionViewLayout,这是控制Itme的摆放位置以及滚动方向的重要类。
以下是继承UICollectionViewFlowLayout,实现的功能是在类似相册的浏览器,只有图片(itme)滚动到中间的时候图片放大.
需要注意的方法有四个(直接拷贝如下四个方法即可实现相册功能)
1.只要显示的边界发生改变就重新布局:
内部会重新调用prepareLayout和layoutAttributesForElementsInRect方法获得所有cell的布局属性
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{returnYES;}
2.一些初始化工作最好在这里实现,比如设置item大小,滚动方向,等等
- (void)prepareLayout {
[super prepareLayout];
// 每个cell的尺寸
self.itemSize = CGSizeMake(ItemWH,ItemWH);
CGFloat inset = (self.collectionView.frame.size.width - ItemWH) * 0.5;
self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
// 设置水平滚动
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.minimumLineSpacing = ItemWH * 0.7;
}
3.
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
// 0.计算可见的矩形框
CGRectvisiableRect;
visiableRect.size=self.collectionView.frame.size;
visiableRect.origin=self.collectionView.contentOffset;
// 1.取得默认的cell的UICollectionViewLayoutAttributes
NSArray*array = [superlayoutAttributesForElementsInRect:rect];
//计算屏幕最中间的x
CGFloatcenterX =self.collectionView.contentOffset.x+self.collectionView.frame.size.width*0.5;
// 2.遍历所有的布局属性
for(UICollectionViewLayoutAttributes*attrsinarray) {
//如果不在屏幕上,直接跳过
if(!CGRectIntersectsRect(visiableRect, attrs.frame))continue;
//每一个item的中点x
CGFloatitemCenterX = attrs.center.x;
//差距越小,缩放比例越大
//根据跟屏幕最中间的距离计算缩放比例
CGFloatscale =1+HZJScaleFactor* (1- (ABS(itemCenterX - centerX) /HZJActiveDistance));
attrs.transform=CGAffineTransformMakeScale(scale, scale);
}
returnarray;
}
4.用来设置collectionView停止滚动那一刻的位置
参数说明:1.proposedContentOffset原本collectionView停止滚动那一刻的位置2.velocity滚动速度
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
// 1.计算出scrollView最后会停留的范围
CGRectlastRect;
lastRect.origin= proposedContentOffset;
lastRect.size=self.collectionView.frame.size;
//计算屏幕最中间的x
CGFloatcenterX = proposedContentOffset.x+self.collectionView.frame.size.width*0.5;
// 2.取出这个范围内的所有属性
NSArray*array = [selflayoutAttributesForElementsInRect:lastRect];
// 3.遍历所有属性ABS()计算绝对值
CGFloatadjustOffsetX =MAXFLOAT;
for(UICollectionViewLayoutAttributes*attrsinarray) {
if(ABS(attrs.center.x- centerX)
adjustOffsetX = attrs.center.x- centerX;
}
}
returnCGPointMake(proposedContentOffset.x+ adjustOffsetX, proposedContentOffset.y);
}