iOS自定义瀑布流详解手机开发

 #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 
 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/3399.html

(0)
上一篇 2021年7月16日
下一篇 2021年7月16日

相关推荐

发表回复

登录后才能评论