#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