collectionView实现瀑布流

来源:互联网 发布:python os.pardir 编辑:程序博客网 时间:2024/05/16 05:35

#import "WaterFlowLayout.h"

#import "ShopModel.h"


@interface WaterFlowLayout()


// 保存每一列最大的Y

@property (nonatomic,strong)NSMutableArray *maxYArray;


@end



// 最大列数

static    NSInteger maxColumn =3;


@implementation WaterFlowLayout



- (NSMutableArray *)maxYArray {

    if (nil ==_maxYArray) {

        _maxYArray = [NSMutableArrayarray];

    }

    return_maxYArray;

}



- (instancetype)init {

    if (self = [superinit]) {

        

    }

    return self;

}


//准备布局的时候调用 ,当布局刷新(改变)

- (void)prepareLayout {

    [superprepareLayout];

}


//当可见范围发生变化的时候就会重新布局

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {

    returnYES;

}


#pragma mark -

#pragma mark - 反回的是每一个cell的属性

// 对每一个cell的属性进行设置, frame(x,y,width, height)

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

    // 确定最大的列数

//    NSInteger maxColumn = 3;

    

    // 确定行间距, 列间距

    CGFloat columnMargin = 10;

    CGFloat rowMargin = 10;

    

    // 确定组的内间距

    UIEdgeInsets sectionInsets = UIEdgeInsetsMake(10, 10, 10, 10);

    

    

    // 取出collectionView size

    CGSize collectionViewSize = self.collectionView.frame.size;

    

    // 确定cell 的宽度

    CGFloat itemWidth = (collectionViewSize.width - sectionInsets.left - sectionInsets.right - (maxColumn - 1) * columnMargin) / maxColumn;

    

    // 确定cell的高度

#warning 计算cell的高度待定

    // 取出对应到 indexPath.item , imageArray 的对象

//    ShopModel *shopModel = _imageArray[indexPath.row];

    // itemW/itemH = w/h

//    CGFloat itemHeight = itemWidth * shopModel.h / shopModel.w;

    

    CGFloat itemHeight = [self.delegatewaterFlowLayout:selfwithIndexPath:indexPathandItemWidth:itemWidth];

    

    // 确定cell x  y

#warning x, y 待计算

   

    

    // 找到 最短的最大Y

    CGFloat minMaxY = [self.maxYArray[0]doubleValue];

    

    // 定义 最短的列

    NSInteger minColumn = 0;

    

    for (int i =1; i <maxColumn; i++) {

        // 取出数组中的Y

        CGFloat arrayY = [self.maxYArray[i]doubleValue];

        

        if (minMaxY > arrayY) {

            // 确定最短的最大Y

            minMaxY = arrayY;

            

            minColumn = i;

        }

    }

    

    CGFloat itemX = minColumn * itemWidth + minColumn * columnMargin + sectionInsets.left;

    

    

    CGFloat itemY = minMaxY + rowMargin;

    

    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:indexPath];

    

    attributes.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);

    

    // 记录 最大Y

    self.maxYArray[minColumn] =@(CGRectGetMaxY(attributes.frame));

    

    return attributes;

}



#pragma mark -

#pragma mark -  反回可见区域的cell属性

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

    // 在每次调用这个方法的时候, 最好把 maxYArray 给清空掉

    [self.maxYArrayremoveAllObjects];

    

    // 对数组做初始化

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

        [self.maxYArrayaddObject:@0];

    }

    

    // 实例化一个可变数组

    NSMutableArray *itemArray = [NSMutableArrayarray];

    

    // 取出当前有多少个cell, 反回第0组有多少个cell

    NSInteger itemCount = [self.collectionViewnumberOfItemsInSection:0];

    

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

        // 创建一个 indexPath

        NSIndexPath *indexPath = [NSIndexPathindexPathForItem:iinSection:0];

        

        // 调用 layoutAttributesForItemAtIndexPath: 返回是对应到indexPath cell的属性

        UICollectionViewLayoutAttributes *attri = [selflayoutAttributesForItemAtIndexPath:indexPath];

        

        // cell的属性放到 可变数组中

        [itemArray addObject:attri];

    }

    

    

    return itemArray;

}


- (CGSize)collectionViewContentSize {

    

    CGFloat maxY = 0;

    

    if (self.maxYArray.count) {

        maxY = [self.maxYArray[0]doubleValue];

        

        for (int i =1; i <maxColumn; i++) {

            CGFloat arryY = [self.maxYArray[i]doubleValue];

            

            if (maxY < arryY) {

                maxY = arryY;

            }

        }

    }

    

    return CGSizeMake(0, maxY +10);

}


@end

========================================================

#import "ViewController.h"

#import "ShopCell.h"

#import "WaterFlowLayout.h"

#import "ShopModel.h"


@interface ViewController ()<UICollectionViewDataSource,WaterFlowLayoutDelegate>


@property (nonatomic,strong)NSArray *dataArray;


@end


static NSString *identifier =@"shopCell";


@implementation ViewController


#pragma mark -

#pragma mark -  懒加载

- (NSArray *)dataArray {

    if (nil ==_dataArray) {

        

        //

        NSString *path = [[NSBundlemainBundle]pathForResource:@"shop.plist"ofType:nil];

        

        

        //

        NSArray *tempArray = [NSArrayarrayWithContentsOfFile:path];

        

        //

        NSMutableArray *mutable = [NSMutableArrayarray];

        

        //

        for (NSDictionary *dictin tempArray) {

            ShopModel *shopModel = [ShopModelshopModelWithDict:dict];

            

            [mutable addObject:shopModel];

        }

        

        // f

        _dataArray = mutable;

    }

    return_dataArray;

}


- (void)viewDidLoad {

    [superviewDidLoad];

    

    // 1. 实例化一个流水布局

    WaterFlowLayout *flowlayout = [[WaterFlowLayoutalloc]init];

    

    // 赋值

//    flowlayout.imageArray = self.dataArray;

    flowlayout.delegate = self;

    

    // 2. 实力化一个collectionView

    UICollectionView *collectionView = [[UICollectionViewalloc]initWithFrame:self.view.boundscollectionViewLayout:flowlayout];

    

    

    // 3. 设置数据源代理

    collectionView.dataSource = self;

    

    // 4. 注册一个cell

    UINib *nib = [UINibnibWithNibName:@"ShopCell"bundle:nil];

    

    [collectionView registerNib:nibforCellWithReuseIdentifier:identifier];

    

    

    // 5. collectionView 添加到控制器的view

    [self.viewaddSubview:collectionView];

}



//

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {

    return 1;

}


//

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

    return self.dataArray.count;

}


//

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    ShopCell *cell = [collectionViewdequeueReusableCellWithReuseIdentifier:identifierforIndexPath:indexPath];

    

    cell.backgroundColor = [UIColorredColor];

    

    cell.shopModel = self.dataArray[indexPath.item];

    //cell的contentView的属性是只读的,不能改变,但是可以在contentView上添加子控件

    return cell;

}



#pragma mark -

#pragma mark - 通过代理方法返回 item的高度

- (CGFloat)waterFlowLayout:(WaterFlowLayout *)waterFlowLayout withIndexPath:(NSIndexPath *)indexPath andItemWidth:(CGFloat)width {

    ShopModel *shopModel = self.dataArray[indexPath.item];

    

    return width * shopModel.h / shopModel.w;

}



@end



0 0
原创粉丝点击