• UICollectionViewLayout继承UICollectionViewFlowLayout自定义布局


    重写prepareLayout方法
    - 作用:在这个方法中做一些初始化操作
    - 注意:一定要调用[super prepareLayout]

    重写layoutAttributesForElementsInRect:方法
    - 作用:
    - 这个方法的返回值是个数组
    - 这个数组中存放的都是UICollectionViewLayoutAttributes对象
    - UICollectionViewLayoutAttributes对象决定了cell的排布方式(frame等)

    重写shouldInvalidateLayoutForBoundsChange:方法
    - 作用:如果返回YES,那么collectionView显示的范围发生改变时,就会重新刷新布局
    - 一旦重新刷新布局,就会按顺序调用下面的方法:
    - prepareLayout
    - layoutAttributesForElementsInRect:

    重写targetContentOffsetForProposedContentOffset:withScrollingVelocity:方法
    - 作用:返回值决定了collectionView停止滚动时最终的偏移量(contentOffset)
    - 参数:
    - proposedContentOffset:原本情况下,collectionView停止滚动时最终的偏移量
    - velocity:滚动速率,通过这个参数可以了解滚动的方向

     下面是具体实现

    - (instancetype)init

    {

        if (self = [super init]) {

        }

        return self;

    }

    /**

     * 当collectionView的显示范围发生改变的时候,是否需要重新刷新布局

     * 一旦重新刷新布局,就会重新调用下面的方法:

     1.prepareLayout

     2.layoutAttributesForElementsInRect:方法

     */

    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

    {

        return YES;

    }

    /**

     * 用来做布局的初始化操作(不建议在init方法中进行布局的初始化操作)

     */

    - (void)prepareLayout

    {

        [super prepareLayout];

        

        // 水平滚动

        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

        

        // 设置内边距

        CGFloat inset = (self.collectionView.frame.size.width - self.itemSize.width) * 0.5;

        self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);

    }

    /**

     UICollectionViewLayoutAttributes *attrs;

     1.一个cell对应一个UICollectionViewLayoutAttributes对象

     2.UICollectionViewLayoutAttributes对象决定了cell的frame

     */

    /**

     * 这个方法的返回值是一个数组(数组里面存放着rect范围内所有元素的布局属性)

     * 这个方法的返回值决定了rect范围内所有元素的排布(frame)

     */

    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

    {

        // 获得super已经计算好的布局属性

        NSArray *array = [super layoutAttributesForElementsInRect:rect];

        

        // 计算collectionView最中心点的x值

        CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;

        

        // 在原有布局属性的基础上,进行微调

        for (UICollectionViewLayoutAttributes *attrs in array) {

            // cell的中心点x 和 collectionView最中心点的x值 的间距

            CGFloat delta = ABS(attrs.center.x - centerX);

            

            // 根据间距值 计算 cell的缩放比例

            CGFloat scale = 1 - delta / self.collectionView.frame.size.width;

            

            // 设置缩放比例

            attrs.transform = CGAffineTransformMakeScale(scale, scale);

        }

        

        return array;

    }

    /**

     * 这个方法的返回值,就决定了collectionView停止滚动时的偏移量

     */

    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity

    {

        // 计算出最终显示的矩形框

        CGRect rect;

        rect.origin.y = 0;

        rect.origin.x = proposedContentOffset.x;

        rect.size = self.collectionView.frame.size;

        

        // 获得super已经计算好的布局属性

        NSArray *array = [super layoutAttributesForElementsInRect:rect];

        

        // 计算collectionView最中心点的x值

        CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;

        

        // 存放最小的间距值

        CGFloat minDelta = MAXFLOAT;

        for (UICollectionViewLayoutAttributes *attrs in array) {

            if (ABS(minDelta) > ABS(attrs.center.x - centerX)) {

                minDelta = attrs.center.x - centerX;

            }

        }

        

        // 修改原有的偏移量

        proposedContentOffset.x += minDelta;

        return proposedContentOffset;

    }

  • 相关阅读:
    JavaScript的alert()突然出现中文乱码
    对ie CSS hack总结和理解
    getBoundingClientRect()获取元素相对浏览器视窗的坐标值
    typeof和instanceof的区别
    转载:Dos命令行下,关闭占用80端口的进程 (~~~这个比较实用!)
    关于JS浮点数计算误差问题和二进制浮点数表示法的思考
    callee与caller,apply与call的区别和作用
    [Javascript权威指南笔记01]后自增/后自减运算符的副作用 和 运算符的结合性
    转载:关于zindex的那些事(~~~比较理论的描述 堆栈上下文)
    西游东去 (~~创意?创新?恶搞?不置可否,不过有点意思)
  • 原文地址:https://www.cnblogs.com/wangliang2015/p/5388658.html
Copyright © 2020-2023  润新知