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;
@end
2>>属性代理PollScrollDelegate
@protocol PollScrollDelegate <NSObject>
@optional
//返回行间距
- (CGFloat)rowOfScroll:(UIScrollView *)jrScroll spaceForCellWithFlag:(PollScrollSpace)jrSpace;
@end
3>>定义代理
@property(nonatomic,weak)id <PollScrollDataSource> pollDataSource;
@property(nonatomic,weak)id <PollScrollDelegate> pollDelegate;
2 瀑布流视图,计算每个cell的位置大小
1>>由代理方法得到获取的每个cell大小位置
//枚举类型设置边距
#define kSpace 10
typedef 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 * [email protected]"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;
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-15 03:09:45