美文网首页iOS Developer
自定义UICollectionViewFlowLayout

自定义UICollectionViewFlowLayout

作者: loongod | 来源:发表于2016-05-05 17:56 被阅读790次

    闲着没事,无意间看到掌上英雄联盟查看皮肤中CollectionView的效果,觉得很不错,趁着机会也学习下UICollectionViewFlowLayout的自定义,先看效果:

    查找资料,发现苹果提供了2个关于Layout的demo,

    Apple demo下载

    LineLayoutDemo下载

    这个基本上就是复制LineLayout的学习,在原来的基础上优化了一点。

    首先创建一个继承与UICollectionViewFlowLayout的类,
    我的.h

    @interface GLCollectionViewFlowLayou : UICollectionViewFlowLayout
    

    实现文件中主要有四个方法:

    //可以在此方法中初始化你的layout
    - (void)prepareLayout {
        //必须调用super
        [super prepareLayout];
    }
    
    //在这里改变布局 滑动时会时时调用此方法
    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    }
    
    //替换最终滑动的contentOffset, proposedContentOffset是预期滑动停止的位置
    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    }
    
    // 当collectionView bounds改变时,是否重新布局
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
        return YES;
    }
    

    苹果的LineLayout在滑到第一个和最后一个的时候,有点问题,不能更新到正确的位置。

    在设置layout的时候设置UICollectionView的_collectionView.contentInset,设置如下:

        CGFloat left = CGRectGetWidth(self.collectionView.frame) / 2 - flowLayout.itemSize.width / 2;
        _collectionView.contentInset = UIEdgeInsetsMake(0, left, 0, left);
    

    customLayout.m中,在targetContentOffsetForProposedContentOffset方法中处理第一个和最后一个的返回的contentOffset:

     //替换希望的contentOffset
        CGPoint actualPoint = CGPointMake(proposedContentOffset.x + minDistance, proposedContentOffset.y);
        
        //处理第一个 和 最后一个的contentOffset
        CGFloat minContentOffsetX = -floor(self.collectionView.contentInset.left);
        CGFloat maxContentOffsetX = floor(self.collectionView.contentSize.width - CGRectGetWidth(self.collectionView.frame) + self.collectionView.contentInset.right);
        actualPoint = actualPoint.x < minContentOffsetX ? CGPointMake(minContentOffsetX, actualPoint.y) : actualPoint;
        actualPoint = actualPoint.x > maxContentOffsetX ? CGPointMake(maxContentOffsetX, actualPoint.y) : actualPoint;
        return actualPoint;
    

    这样就OK了,滑倒第一个和最后一个也可以正常的显示和滚动了。

    Demo地址:

    点我哦


    相关文章

      网友评论

        本文标题:自定义UICollectionViewFlowLayout

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