iOS自定义瀑布流布局

最近上班比较无聊,闲来无事就在网上随便下项目看。

今天就来看看自定义瀑布流布局。

自定义瀑布流布局主要是新建一个继承自UICollectionViewFlowLayout的类,重点是实现该类中的一个方法:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect   在这个方法里面,我们要算出每个item的文字和尺寸并返回给系统;

当该类被我们调用时系统会依次执行下列方法:

(1)- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds :当collectionView的显示范围发生改变的时候,是否需要重新刷新布局
 一旦重新刷新布局,就会调用下面两个方法;

(2)- (void)prepareLayout :我们一般在这里执行一些初始化的操作

(3)- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect   在这个方法里面,我们要算出每个item的文字和尺寸并赋值给每一个          UICollectionViewLayoutAttributes,然后返回给系统, 系统根据这个数组的布局属性展示collectionView,到这里自定义就搞定了。

当然,在这里我们也可以监听下面这个方法来控制congtenoffset:

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

下面现学现卖,自定义布局实现之前项目的一个功能:

之前的一个项目有一个需求:要求做成如下的分页效果

毫无疑问,这个功能肯定用UICollectionView来搞定它,但是难点就是这种不连续的分页效果,做起来比较麻烦。之前不知道重写UICollectionViewFlowLayout,于是在控制器里面直接监听- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity  这个方法,这算起来就十分蛋疼了,不行你可以试着玩玩。

但是!重点来了,如果通过继承UICollectionViewFlowLayout自定义一个布局,在这里面监听上面那个方法,那就爽歪歪了。我们可以轻松地拿到系统算好的布局,在这个布局的基础上做微调就可以了,核心代码就几句话:

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{
    CGRect rect;
    rect.origin.x = proposedContentOffset.x;
    rect.origin.y = 0;
    rect.size = self.collectionView.frame.size;
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    CGFloat collectionCenterX = self.collectionView.frame.size.width*0.5 + proposedContentOffset.x;
    CGFloat minDelta = MAXFLOAT;
    // 核心:判断collectionView的中心离哪个item更近就让那个item显示在中央
    for (UICollectionViewLayoutAttributes *attrs in array) {
        if (fabs(minDelta)>fabs(attrs.center.x-collectionCenterX)) {
            minDelta = attrs.center.x-collectionCenterX;
        }
    }
    proposedContentOffset.x+=minDelta;
    return proposedContentOffset;
}

这里我们只是拿到系统算好的布局再做偏移,所以不必重新算布局。

如果要做想天猫商品展示不等高的界面,如图:

这种界面的思路就是布局固定两列,遍历商品数据逐个把商品加到列高比较小的那一列,算出各个item的布局属性(我们必须知道图片的宽高比),这种算起来就稍微麻烦一点了。

 

posted @ 2016-12-23 16:09  闲云野鹤天马行空  阅读(1014)  评论(0编辑  收藏  举报