瀑布流的实现原理

来源:互联网 发布:软件开发有哪些 编辑:程序博客网 时间:2024/05/26 19:19

瀑布流的实现不同的人有不同的方法,个人认为最靠谱的莫过于用UICollectionView来实现,只要明白其中的思想实现起来先就非常简单了,其实博主也是在网上看别人写的demo,下载下来研究弄明白的,给大家展示一下效果图。


第一步、自定义UICollectionViewLayout,在.h文件中定义协议,协议方法有下面四个。

@class CustomCollectionViewLayout;@protocol CustomCollectionViewLayoutDelegate <NSObject>@required/** *  @brief 每个cell之间的间距 */-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout marginOfCellWithCollectionView:(UICollectionView *)collectionView;/** *  @brief cell的最小高度 */-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout minHeightOfCellWithCollectionView:(UICollectionView *)collectionView;/** *  @brief cell的最大高度 */-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout maxrOfCellWithCollectionView:(UICollectionView *)collectionView;/** *  @brief 行数 */-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout numberOfColumnWithCollectionView:(UICollectionView *)collectionView;@end
第二步、在.m文件中定义属性,实现协议方法

@interface CustomCollectionViewLayout ()@property (nonatomic,assign) NSInteger numberOfSections;//section的数量@property (nonatomic,assign) NSInteger  numberOfCellInSections;//section中cell的数量@property (nonatomic,assign) NSInteger  columnCount;//行数@property (nonatomic,assign) NSInteger  margin;//cell之间的间距@property (nonatomic,assign) NSInteger  cellMinHeight;//cell的最小高度@property (nonatomic,assign) NSInteger  cellMaxHeight;//cell的最大高度@property (nonatomic,assign) NSInteger  cellWidth;//cell的宽度@property (nonatomic,strong) NSMutableArray * cellHeightArray;//存储每个cell的随机高度@property (nonatomic,strong) NSMutableArray * cellXArray;//存储每列cell的X坐标@property (nonatomic,strong) NSMutableArray * cellYArray;//存储每列cell的最新cell的Y坐标@end
- (void)initCustonCollectionViewLayoutDate{    _numberOfSections = [self.collectionView numberOfSections];    _numberOfCellInSections = [self.collectionView numberOfItemsInSection:0];    _margin = [_delegate CustomCollectionViewLayout:self marginOfCellWithCollectionView:self.collectionView];    _columnCount = [_delegate CustomCollectionViewLayout:self numberOfColumnWithCollectionView:self.collectionView];    _cellMinHeight = [_delegate CustomCollectionViewLayout:self minHeightOfCellWithCollectionView:self.collectionView];    _cellMaxHeight = [_delegate CustomCollectionViewLayout:self maxrOfCellWithCollectionView:self.collectionView];}
第三步、重写prepareLayout方法,在这个方法中我们要初始化一些数据

/** *  @brief 预加载layout,只会被执行一次 */- (void)prepareLayout{    [super prepareLayout];    [self initCustonCollectionViewLayoutDate];    [self initCustonCollectionViewLayoutCellWidth];    [self initCustonCollectionViewLayoutCellHeight];}
第四步、实现核心方法,就是为每一个cell绑定一个Layout属性

-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{    [self initCellYArray];    NSMutableArray * array = [NSMutableArray array];    for (int i = 0; i < _numberOfCellInSections; i ++) {        NSIndexPath * indexPath = [NSIndexPath indexPathForItem:i inSection:0];        UICollectionViewLayoutAttributes * attributes = [self layoutAttributesForItemAtIndexPath:indexPath];        [array addObject:attributes];    }    return array;}-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{    UICollectionViewLayoutAttributes * attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];    CGRect frame = CGRectZero;    CGFloat cellHeight = [[_cellHeightArray objectAtIndex:indexPath.row] floatValue];    NSInteger minYIndex = [self selectMinIndexWithArray:_cellYArray];    CGFloat X = [[_cellXArray objectAtIndex:minYIndex] floatValue];    CGFloat Y = [[_cellYArray objectAtIndex:minYIndex] floatValue];    frame = CGRectMake(X, Y, _cellWidth, cellHeight);    _cellYArray[minYIndex] = @(Y + cellHeight + _margin);//更新相应的Y坐标    attributes.frame = frame;//计算每个cell的位置    return attributes;}
第五步、集成。如果是用StoryBoard拖得可能稍微简单一点,当然代码书写也不难。拿到代理,实现代理方法就行。

#pragma mark --- CustomCollectionViewLayoutDelegate-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout marginOfCellWithCollectionView:(UICollectionView *)collectionView{    return 2;}-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout maxrOfCellWithCollectionView:(UICollectionView *)collectionView{    return 150;}-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout minHeightOfCellWithCollectionView:(UICollectionView *)collectionView{    return 100;}-(NSInteger)CustomCollectionViewLayout:(CustomCollectionViewLayout *)collectionViewLayout numberOfColumnWithCollectionView:(UICollectionView *)collectionView{    return 2;}
注意点:如果是用StoryBoard拖一定注意cell的重用、Layout的指定(因为我们自定义了UICollectionViewLayout);代码是实现的话就需要细心一点儿就ok。

代码传送门:https://github.com/fuzongjian/WaterFall.git




0 0