【iOS】瀑布流的实现

2020-03-28 20:58:07 浏览数 (1)

1、效果演示

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

2、实现思路

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

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

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

代码语言:javascript复制
- (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从数据源获取

代码语言:javascript复制
CGFloat itemHeight = [self.dataSource waterFallLayout:self itemHeightForItemWidth:itemWidth atIndexPath:attributes.indexPath];

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

代码语言:javascript复制
/// 找出最短的一列
    __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重写以下方法

代码语言:javascript复制
/// 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

0 人点赞