UICollectionView的使用
- 1.一定要初始化布局*
- 2.设置数据源,展示 ,代理:处理cell点击
- 3.cell必须通过注册 *
- 4.cell必须要自定义 *
如果要在滚动的时候改变cell,那么就要实现以下方法来设置cell的布局,系统的布局不能满足我们的要求,因此我们要自定义布局,并且在方法中一定要调用super父类的相应方法
方法一
/*
方法一:
返回cell布局,可以获取cell布局,直接操作cell尺寸
作用:指定一段区域,就能返回这个区域内所有cell布局,可以一次性返回所有的布局
*/
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
//拿到系统返回的所有的cell布局,对其进行修改,然后返回
//获取已经显示出来的cell的布局
NSArray *atts = [super layoutAttributesForElementsInRect:self.collectionView.bounds];
//偏移量
CGFloat offsetX = self.collectionView.contentOffset.x;
CGFloat W = self.collectionView.bounds.size.width;
for (UICollectionViewLayoutAttributes *cellAtt in atts) {
//cell离中心点距离为marginToCenter(显示出来的cell的中心点X值减去CollectionView宽度的一半与CollectionView偏移量的和)
//距离不能是负数,因此要取绝对值
CGFloat marginToCenter = fabs(cellAtt.center.x - (offsetX + W * 0.5));
//获取缩放比例
CGFloat scale = 1 - marginToCenter / (0.5 * W) * 0.25;
NSLog(@"%f",scale);
//形变
cellAtt.transform = CGAffineTransformMakeScale(scale, scale);
}
return atts;
}
方法二
/*
方法二:
Invalidate:刷新
在滚动的时候是否刷新布局
*/
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
//自己验证的是系统默认返回NO,也就是不允许在滚动的时候刷新,也就是下面的prepareLayout只会在collectionView第一次显示的时候调用,返回YES的时候,就会在滚动的时候不停的调用
// return [super shouldInvalidateLayoutForBoundsChange:newBounds];
return YES;
}
方法三
/*
方法三:
作用:返回最终偏移量
调用时刻:当用户手指抬起时,拖动完成的时候就会调用
*/
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
//最终偏移量 =? 手指抬起时候的偏移量collectionView的偏移量
//慢慢拖,相等 ,如果很快的拖动,就不相等,这个是因为惯性,collectionView还要减速继续滚动到停止
CGFloat W = self.collectionView.bounds.size.width;
//获取最终显示的cell
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, W, MAXFLOAT);
//给定一个区域,获取最终显示的cell
NSArray *atts = [super layoutAttributesForElementsInRect:targetRect];
//遍历数组,获取cell中心点离collectionView最近的那个cell
CGFloat minMargin = MAXFLOAT;
for (UICollectionViewLayoutAttributes *cellAtt in atts) {
CGFloat marginToCenter = cellAtt.center.x - (proposedContentOffset.x + W * 0.5);
if (fabs(marginToCenter) < fabs(minMargin)) {
minMargin = marginToCenter;
}
}
proposedContentOffset.x += minMargin;
NSLog(@"%f",proposedContentOffset.x);
//如果在程序运行之后,将collectionView向左边移动一点点,会出现最终偏移量为-0的情况,要解决这个bug,就要写下面的代码,不让它的偏移量出现负数
if (proposedContentOffset.x < 0) {
proposedContentOffset.x = 0;
}
return proposedContentOffset;
}
方法四
/*
方法四:
必须要调用[super prepareLayout]
作用:计算所有cell布局,前提条件,cell布局不会经常改变,是固定死
时刻:第一次要显示collectionView才会调用,每次collectionView刷新都会调用
*/
- (void)prepareLayout
{
[super prepareLayout];
}
方法五
/*
方法五:
返回滚动范围
*/
-(CGSize)collectionViewContentSize
{
//返回0的时候什么都没有
// return CGSizeZero;
return [super collectionViewContentSize];
}