重复利用的瀑布流视图

来源:互联网 发布:centos安装新内核 编辑:程序博客网 时间:2024/06/06 03:36

Step1 ===封装自定义的UIScrollView控制器

1 协议代理方法

1>>数据源代理PollScrollDataSource@protocol PollScrollDataSource <NSObject>@required//返回总列数- (NSInteger)numberOfColums:(UIScrollView *)jrScroll;//返回cell总个数- (NSInteger)numberOfCells:(UIScrollView *)jrScroll;//返回每个cell的实际宽高- (CGSize)sizeOfCellInScroll:(UIScrollView *)jrScroll cellAtIndex:(NSInteger)index;//返回cell视图- (UIView *)jrScroll:(UIScrollView *)jrScroll cellAtIndex:(NSInteger)index;@end2>>属性代理PollScrollDelegate@protocol PollScrollDelegate <NSObject>@optional//返回行间距- (CGFloat)rowOfScroll:(UIScrollView *)jrScroll spaceForCellWithFlag:(PollScrollSpace)jrSpace;@end3>>定义代理@property(nonatomic,weak)id <PollScrollDataSource> pollDataSource;@property(nonatomic,weak)id <PollScrollDelegate> pollDelegate;

2 瀑布流视图,计算每个cell的位置大小

1>>由代理方法得到获取的每个cell大小位置//枚举类型设置边距#define kSpace 10typedef enum {    topScrollSpace,//上边距    bottomScrollSpace,//下边距    leftScrollSpace,//左边距    rightScrollSpace,//右边距    rowScrollSpace,//行边距    columnScrollSpace//列边距   }PollScrollSpace; //获取cell总数    NSInteger totalCell=[self.pollDataSource numberOfCells:self];    //获取总列数--如果列=0,则返回默认值3    NSInteger totalColum=[self.pollDataSource numberOfColums:self];    if (!totalColum) {        totalColum=3;    }    //获取上、下、左、右、行、列间距---如果没有响应实现代理方法,设置默认值    CGFloat topSpace=kSpace,bottomSpace=kSpace,leftSpace=kSpace,rightSpace=kSpace,rowSpace=kSpace,columnSpace=kSpace;    if ([self.pollDelegate respondsToSelector:@selector(rowOfScroll:spaceForCellWithFlag:)]) {        topSpace=[self.pollDelegate rowOfScroll:self spaceForCellWithFlag:topScrollSpace];        bottomSpace=[self.pollDelegate rowOfScroll:self spaceForCellWithFlag:bottomScrollSpace];        leftSpace=[self.pollDelegate rowOfScroll:self spaceForCellWithFlag:leftScrollSpace];        rightSpace=[self.pollDelegate rowOfScroll:self spaceForCellWithFlag:rightScrollSpace];        rowSpace=[self.pollDelegate rowOfScroll:self spaceForCellWithFlag:rowScrollSpace];        columnSpace=[self.pollDelegate rowOfScroll:self spaceForCellWithFlag:columnScrollSpace];        }    CGFloat coorArray[totalColum];    for (int i=0; i<totalColum; i++) {//重新把数组初始化一下        coorArray[i]=0;    }    for (int i=0;i<totalCell; i++) {         //计算所有frame        //找到最低的位置        CGFloat height=coorArray[0];        NSInteger index=0;        for(int j=0; j<totalColum; j++){            if (coorArray[j] < height) {                height=coorArray[j];                index=j;            }        }        //计算frame        //获取实际图像的宽高,是从plist里面得到的实际宽、高        CGSize frame=[self.pollDataSource sizeOfCellInScroll:self cellAtIndex:i];        //设置每一个cell的宽高        self.cellWidth=((self.frame.size.width-leftSpace-rightSpace)-columnSpace*(totalColum-1))/totalColum;        self.cellHeight=self.cellWidth*frame.height/frame.width;//w h 由间距确定宽度,然后等比例缩放得到高度        //相邻cell之间的间距        CGFloat vSpace=self.cellHeight+rowSpace;//两个纵向cell之间的距离        CGFloat hSpace=self.cellWidth+columnSpace;//两个横向cell距离  //每一个cell所在的位置        CGRect frames=CGRectMake(index*hSpace+leftSpace,height+rowSpace,self.cellWidth,self.cellHeight);        NSValue * value=[NSValue valueWithCGRect:frames];            ///更新数组数据        coorArray[index]=CGRectGetMaxY(frames);        [self.frameArray addObject:value];    }    //获取最大的height    CGFloat maxHeight=coorArray[0];    for (int j=0; j<totalColum; j++) {        if (coorArray[j]>maxHeight) {            maxHeight=coorArray[j];        }    }self.contentSize=CGSizeMake(0, maxHeight+10);

3 可以重复利用的瀑布流视图

1>>渲染瀑布流视图方法- (void)layoutSubviews{    [super layoutSubviews];    for (int i=0; i<self.frameArray.count; i++) {        NSValue * value=self.frameArray[i];        CGRect frame=[value CGRectValue];        BOOL isInScreen=[self _isInScreen:frame];        if(isInScreen){            //在屏幕上时有两种情况---1>之前已经添加过(不做处理)--2>刚进入屏幕的(加入字典)            if(!self.inScreenDic[@(i)]){//之前不在屏幕出现的加入字典                UIView * view=[self.pollDataSource jrScroll:self cellAtIndex:i];                view.frame=frame;                [self addSubview:view];//加载到视野屏幕上                [self.inScreenDic setObject:view forKey:@(i)];//加入到字典            }         }        else{            //如果从屏幕上离开,从屏幕父视图上移除并且从字典中删除            UIView * cell=self.inScreenDic[@(i)];            if(jrCell){                //加入到缓存池                NSMutableSet * set=self.poolDic[jrCell.identy];                [set addObject:jrCell];                [jrCell removeFromSuperview];//从屏幕移除                [self.inScreenDic removeObjectForKey:@(i)];//从字典删除            }        }    }}2>>判断是不是在屏幕上- (BOOL)_isInScreen:(CGRect)frame{    CGFloat contentY=self.contentOffset.y;    BOOL condition=CGRectGetMaxY(frame)>contentY && frame.origin.y<contentY+self.frame.size.height;    return condition;}

4 获取可以重复利用的cell视图

- (UIView *)dequeueReuseCellWithIdenty:(NSString *)identy{    NSMutableSet * set=self.poolDic[identy];    if (set==nil) {        set=[NSMutableSet set];        [self.poolDic setObject:set forKey:identy];    }    UIView * view=[set anyObject];    if (view) {        [set removeObject:view];    }    return view;}

Step2 ===瀑布流实现

1>>加载数据(plist文件)- (void)_loadData{    //从plist里面获取数据存入到数组    NSString * path=[[NSBundle mainBundle]pathForResource:@"file.plist" ofType:nil];    self.dataArray=[NSArray arrayWithContentsOfFile:path];}2>>调用所定义的UIScrollView,实现代理- (void)_loadSubviews{    UIScrollView * scrollView=[[UIScrollView alloc]initWithFrame:self.view.bounds];    scrollView.pollDataSource=self;    scrollView.pollDelegate=self;    self.scrollView=scrollView;    [self.view addSubview:scrollView];  }3>>代理方法#pragma mark - PollDataSource//返回总列数- (NSInteger)numberOfColums:(UIScrollView *)jrScroll{    return 3;}//返回cell总个数- (NSInteger)numberOfCells:(UIScrollView *)jrScroll{    return self.dataArray.count;}//返回每个cell的实际宽高- (CGSize)sizeOfCellInScroll:(UIScrollView *)jrScroll cellAtIndex:(NSInteger)index{    NSDictionary * temDic=self.dataArray[index];    self.width=[temDic[@"w"] floatValue];    self.height=[temDic[@"h"] floatValue];    return CGSizeMake(self.width, self.height);}//返回cell视图- (UIView *)jrScroll:(UIScrollView *)jrScroll cellAtIndex:(NSInteger)index{    static NSString * identy=@"myCell";    UIView * cell=[jrScroll dequeueReuseCellWithIdenty:identy];//创建可以重复循环利用的cell    if(cell==nil){        cell=[[UIView alloc]initWithReuseIdentifier:identy];//        NSLog(@"====>%li",index);    }    NSDictionary * dic=self.dataArray[index];    cell.imgSrc=dic[@"img"];    cell.textLabel.text=dic[@"price"];    return cell;}#pragma mark - PollDelegate//返回行间距- (CGFloat)rowOfScroll:(UIScrollView *)jrScroll spaceForCellWithFlag:(PollScrollSpace)jrSpace{    switch (jrSpace) {        case topScrollSpace:            return 20;        case bottomScrollSpace:            return 10;        case leftScrollSpace:            return 10;        case rightScrollSpace:            return 10;        case rowScrollSpace:            return 10;        case columnScrollSpace:            return 10;        default:            return 10;    }}
0 0
原创粉丝点击