iOS开发瀑布流的实现

 //自定义布局,继承于UICollectionViewLayout

#import <UIKit/UIKit.h>

 

@class WaterFlowLayout;

 

@protocol  WaterFlowLayoutDeleagre ;

 

 @interface WaterFlowLayout : UICollectionViewLayout

 @property (nonatomic,weak)id<WaterFlowLayoutDeleagre>delegate;

 @end

 

@protocol WaterFlowLayoutDeleagre <NSObject>

@required

- (CGFloat)collectionView:(__kindof UICollectionView *)collectionView heightForItemAtIndexPath:(NSIndexPath *)indexPath;

@end

 

-------------------------------------------------------------------------

 

#import "WaterFlowLayout.h"

 

static  CGFloat const  coloumMarginDefault = 10;  //间隙

 

static NSInteger const coloumDefault = 3; //这里可以更改列数

 

static CGFloat const rowMaginDegault = 10;   //行之间的间隙

   

@interface WaterFlowLayout ()

 

@property (nonatomic,strong)NSMutableArray *   attris;

 

@property (nonatomic,strong)NSMutableArray * cloumsHeight;

@end

 

@implementation WaterFlowLayout

 

 

//记录没列cell的最大Y值

- (NSMutableArray *)cloumsHeight

{

    if (_cloumsHeight == nil) {

        _cloumsHeight = [NSMutableArray array];

    }

    return _cloumsHeight;

}

 

//存放每个cell的属性值

- (NSMutableArray *)attris

{

    if (_attris == nil) {

        _attris = [NSMutableArray array];

    }

    return _attris;

}

 

//准备开始布局

- (void)prepareLayout

{

    [super prepareLayout];

    

    //布局开始之前清空所有的列高度

    [self.cloumsHeight removeAllObjects];

   

    //为列高度添加初始值

    for (int i=0; i<coloumDefault; i++) {

        [self.cloumsHeight addObject:@0];

    }

    //获取对应组的cell个数

    NSInteger count  = [self.collectionView  numberOfItemsInSection:0];

    

    NSMutableArray * atts = [NSMutableArray array];

    //创建cell的布局属性

    for (int i=0; i<count; i++) {

        //获取collectionview中对应indexpath的cell属性

        UICollectionViewLayoutAttributes * attributes   =   [self  layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];

                [atts addObject:attributes];

    }

    

    self.attris = atts;

}

 

- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{

    //返回所有cell的布局属性

    return   self.attris;

}

 

- (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

{

    //初始化布局属性

    UICollectionViewLayoutAttributes * attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    

    //让纪律每列高度中的数组的第一个数据为最小值

    CGFloat minHeight = [self.cloumsHeight[0]  floatValue];

    //记录的列号

    NSInteger   cloum  =0;

    

    //取出最小高度的列

    for ( NSInteger i=1; i<self.cloumsHeight.count; i++) {

         if (minHeight > [self.cloumsHeight[i]  floatValue]) {

            minHeight = [self.cloumsHeight[i]  floatValue];

            cloum =i;

        }

       }

    //计算宽度

    CGFloat W = (self.collectionView.frame.size.width - coloumMarginDefault * (coloumDefault + 1))/ coloumDefault;

   //计算高度

    CGFloat H = [self.delegate collectionView:self.collectionView heightForItemAtIndexPath:indexPath];

    //计算cell的x值

    CGFloat X = coloumMarginDefault + (W +  coloumMarginDefault) *cloum;

    //计算cell的Y值

    CGFloat Y = minHeight + rowMaginDegault;

     attributes.frame = CGRectMake(X, Y, W, H);

    

   //更新记录每列高度的数组

    [self.cloumsHeight   replaceObjectAtIndex:cloum withObject:@(CGRectGetMaxY(attributes.frame) )];

     return attributes;

}

 

//返回collectionview的滚动范围

- (CGSize)collectionViewContentSize

{

    CGFloat maxHeight = 0;

    for (int i=0; i<self.cloumsHeight.count; i++) {

        if (maxHeight < [self.cloumsHeight[i]  floatValue]) {

            maxHeight =[self.cloumsHeight[i]  floatValue];

        }

    }

        return     CGSizeMake(0, maxHeight);

}

 @end

-----------------------------------------------------------------------------------------------如此即可------------------------------------------------

posted @ 2016-07-22 13:27  sujianbo  阅读(290)  评论(0编辑  收藏  举报