iOS自定义瀑布流

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

 #define kWidth self.frame.size.width

#define kHeight self.frame.size.height


@interface JRScrollView()

@property (nonatomic, strong) NSMutableArray * frameArray;

@property (nonatomic, strong) NSMutableDictionary * temDic;

@property (nonatomic, strong) NSMutableSet * temSet;

@property (nonatomic, strong) NSMutableDictionary * inDic;

@end


@implementation JRScrollView

//懒加载

- (NSMutableArray *)frameArray

{

    if (_frameArray == nil)

    {

        _frameArray = [NSMutableArray array];

    }

    return _frameArray;

}


- (NSMutableDictionary *)temDic

{

    if (_temDic == nil)

    {

        _temDic = [NSMutableDictionary dictionary];

    }

    return _temDic;

}


- (NSMutableSet *)temSet

{

    if (_temSet == nil)

    {

        _temSet = [NSMutableSet set];

    }

    return _temSet;

}


- (NSMutableDictionary *)inDic

{

    if (_inDic == nil)

    {

        _inDic = [NSMutableDictionary dictionary];

    }

    return _inDic;

}


//初始化

- (instancetype)initWithFrame:(CGRect)frame

{

    if (self = [super initWithFrame:frame])

    {

        self.showsVerticalScrollIndicator = NO;

        self.backgroundColor = [UIColor whiteColor];

    }

    return self;

}


//加载数据

- (void)loadDataWithArray:(NSMutableArray *)array

{

    //获得列数

    NSInteger colums = 3;

    if ([self.delegateMe respondsToSelector:@selector(numberOfColums:)])

    {

        colums = [self.delegateMe numberOfColums:self];

    }

    

    //获取cell数

    NSInteger count = 0;

    if ([self.dataSourceMe respondsToSelector:@selector(numberOfCell:)])

    {

        count = [self.dataSourceMe numberOfCell:self];

    }

    

    //计算左右间距

    CGFloat marginLR = 10;

    

    //计算上下间距

    CGFloat marginUD = marginLR;

    

    //计算cell宽度

    CGFloat cellW = (kWidth-marginLR*(colums+1))/colums;

    

    //标记每一列的做大Y值

    NSMutableArray * maxYAry = [NSMutableArray array];

    for (int i = 0; i<colums; i++)

    {

        NSMutableDictionary * dic = [NSMutableDictionary dictionary];

        [dic setObject:@(0) forKey:@"maxY"];

        

        //计算放在这一列的x坐标

        CGFloat cellX = (cellW+marginLR)*i+marginLR;

        [dic setObject:@(cellX) forKey:@"cellX"];

        

        //添加数组

        [maxYAry addObject:dic];

    }

    

    //计算高度和坐标

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

    {

        JRCellModel * model = array[i];

        

        //计算cell高度

        CGFloat cellH = model.h*cellW/model.w;


        //获取maxY最小的一列

        [maxYAry sortUsingComparator:^NSComparisonResult(id obj1, id obj2)

        {

            return [obj1[@"maxY"] doubleValue] - [obj2[@"maxY"] doubleValue];

        }];

        NSMutableDictionary * dic = [maxYAry firstObject];

        

        //cell放在那一列(x值)

        CGFloat cellX = [dic[@"cellX"] doubleValue];

        

        //cell的y值

        CGFloat cellY = [dic[@"maxY"] intValue] + marginUD;

        

        //更新这个字典的属性

        CGFloat tempY = cellY+cellH;

        [dic setObject:@(tempY) forKey:@"maxY"];

        

        //创建frame,加入数组

        CGRect frame = CGRectMake(cellX, cellY, cellW, cellH);

        [self.frameArray addObject:[NSValue valueWithCGRect:frame]];

        

        //计算contentsize

        if (i == count - 1) self.contentSize = CGSizeMake(kWidth, tempY+marginUD);

        

    }


//布局

- (void)layoutSubviews

{

    [super layoutSubviews];

    

    //判断frame在不在视野中

    BOOL isIn;

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

    {

        CGRect frame = [self.frameArray[i] CGRectValue];

        CGFloat offsetY = self.contentOffset.y;

        isIn = offsetY<CGRectGetMaxY(frame) && (offsetY+self.frame.size.height)>CGRectGetMinY(frame);

        

        //在,新添加的(原来有的不处理)

        if(isIn)

        {

            if(!self.inDic[@(i)])

            {

                //添加新的视图

                JRCell * cell = [self.dataSourceMe scroll:self cellAtIndex:i];

                cell.frame = [self.frameArray[i] CGRectValue];

                [self addSubview:cell];

                

                //处理inDic字典

                [self.inDic setObject:cell forKey:@(i)];

            }

        }

        //不在,新删除的(一直不在的不处理)

        else

        {

            JRCell * cell = self.inDic[@(i)];

            if(cell)

            {

                NSMutableSet * set = self.temDic[cell.reuseableID];

                [set addObject:cell];

                

                [self.inDic removeObjectForKey:@(i)];

                [cell removeFromSuperview];

            }

        }

    }

}


//重复利用

- (JRCell *)dequWithReusedableID:(NSString *)ID

{

    NSMutableSet * set = self.temDic[ID];

    if (!set)

    {

        set = [NSMutableSet set];

        [self.temDic setObject:set forKey:ID];

    }

//    NSLog(@"%li", set.count);

    JRCell * cell = [set anyObject];

    if (cell)

    {

        [set removeObject:cell];

    }

    

    return cell;

}


@end