美文网首页
UICollectionView自定义流水布局

UICollectionView自定义流水布局

作者: MarceauHe | 来源:发表于2016-04-07 16:19 被阅读485次

    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];
    }
    

    相关文章

      网友评论

          本文标题:UICollectionView自定义流水布局

          本文链接:https://www.haomeiwen.com/subject/ilamlttx.html