首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【iOS】瀑布流的实现

【iOS】瀑布流的实现

作者头像
MapleYe
发布2020-03-28 20:58:07
1.9K0
发布2020-03-28 20:58:07
举报
文章被收录于专栏:MapleYeMapleYe

1、效果演示

Simulator Screen Shot - iPhone 8 - 2020-01-16 at 17.32.16.png

2、实现思路

根据瀑布流的列数,创建记录maxY的字典,例如两列的瀑布流,就创建两个Key去记录左右两列当前最大的maxY

// 初始化字典,有几列就有几个键值对,key为列,value为列的最大y值,
// 初始值为上内边距
for (int i = 0; i < self.column; i++) {
     self.maxYDic[@(i)] = @(self.sectionInset.top);
}

根据设置的列数,列间隙,以及左右inset,确定itemWidth

- (CGFloat)itemWidth
{
    CGFloat collectionViewWidth = self.collectionView.frame.size.width;
    if (collectionViewWidth == 0) {
        collectionViewWidth = [UIScreen mainScreen].bounds.size.width;
    }
    CGFloat itemWidth = (collectionViewWidth - self.sectionInset.left - self.sectionInset.right - (self.column) * self.columnSpacing * (self.column - 1)) / self.column;
    return itemWidth;
}

itemHeight从数据源获取

CGFloat itemHeight = [self.dataSource waterFallLayout:self itemHeightForItemWidth:itemWidth atIndexPath:attributes.indexPath];

判断最小的maxY在左列,还是右列,确定itemY和itemX,从而确定item的frame

/// 找出最短的一列
    __block NSNumber *minIndex = @(0);
    [self.maxYDic enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSNumber *obj, BOOL * _Nonnull stop) {
        if ([self.maxYDic[minIndex] floatValue] > [obj floatValue]) {
            minIndex = key;
        }
    }];
    // 根据最短列去计算itemX
    CGFloat itemX = self.sectionInset.left + (self.columnSpacing + itemWidth) * minIndex.intValue;
    CGFloat itemY = 0;
    if (self.column == 1) {
        // 一列情况
        if (indexPath.row == 0 ) {
            itemY = [self.maxYDic[minIndex] floatValue];
        }else{
            itemY = [self.maxYDic[minIndex] floatValue] + self.rowSpacing;
        }
    }else{
        // 瀑布流多列情况
        // 第一行Cell不需要添加RowSpacing, 对应的indexPath.row = 0 && =1;
        if (indexPath.row == 0 || indexPath.row == 1) {
            itemY = [self.maxYDic[minIndex] floatValue];
        }else{
            itemY = [self.maxYDic[minIndex] floatValue] + self.rowSpacing;
        }
    }
    attributes.frame = CGRectMake(itemX, itemY , itemWidth, itemHeight);

以上就是核心代码和思路,具体代码请下载源码

3、需要重写的方法

继承UICollectionViewLayout重写以下方法

/// 1、初始化数据源
- (void)prepareLayout
/// 2、计算每个Attribute
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
/// 3、返回数据源
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
/// 4、返回itemSize
- (CGSize)collectionViewContentSize

4、下载地址

https://github.com/maple1994/MPPlayerDemo

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、效果演示
  • 2、实现思路
  • 3、需要重写的方法
  • 4、下载地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档