#define kSpace 20
@interface JRScrollView(){
CGFloat kViewWidth;
CGFloat kViewHeight;
}
/** 保存所有frame*/
@property(nonatomic,strong) NSMutableArray * frameArray;
/** 保存所有在屏幕内的视图frame*/
@property(nonatomic,strong) NSMutableDictionary * inDic;
/** 保存缓冲池*/
@property(nonatomic,strong) NSMutableDictionary * poolDic;
@end
@implementation JRScrollView
-(NSMutableArray *)frameArray{
if (_frameArray==nil) {
_frameArray=[NSMutableArray array];
}
return _frameArray;
}
-(NSMutableDictionary *)inDic{
if (_inDic==nil) {
_inDic=[NSMutableDictionary dictionary];
}
return _inDic;
}
-(NSMutableDictionary *)poolDic{
if (_poolDic==nil) {
_poolDic=[NSMutableDictionary dictionary];
}
return _poolDic;
}
//.....
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
#pragma mark - 加载子视图
- (void) _addSubviews{
//获取当前cell的尺寸
kViewHeight=[self.jrDelegate sizeOfCellInScroll:self].height;
kViewWidth=[self.jrDelegate sizeOfCellInScroll:self].width;
//获取当前总的cell数目
NSInteger totalCells=[self.jrDatasource numberOfCells:self];
//获取当前列数
NSInteger colums=[self.jrDatasource numberofColums:self];
CGFloat leftSpace, rightSpace, topSpace, rowSpace;
leftSpace=rightSpace=topSpace=rowSpace = kSpace;
if ([self.jrDelegate respondsToSelector:@selector(jrsCroll:spaceForCellWithFlag:)]) {
//获取左间距
leftSpace=[self.jrDelegate jrsCroll:self spaceForCellWithFlag:JRScrollViewSpaceLeft];
//获取右间距
rightSpace=[self.jrDelegate jrsCroll:self spaceForCellWithFlag:JRScrollViewSpaceRight];
//获取顶部间距
topSpace=[self.jrDelegate jrsCroll:self spaceForCellWithFlag:JRScrollViewSpaceTop];
//获取行间距
rowSpace=[self.jrDelegate jrsCroll:self spaceForCellWithFlag:JRScrollViewSpaceRowSpace];
}
//计算所有的frame,用来判断是否在显示的视野内
//水平间距
CGFloat hspace=(self.frame.size.width-leftSpace-rightSpace-colums*kViewWidth)/(colums-1)+kViewWidth;
if ([self.jrDelegate respondsToSelector:@selector(hspaceForJrsCroll:)]) {
hspace = [self.jrDelegate hspaceForJrsCroll:self] + kViewWidth;
}
//竖直间距
CGFloat vspace=kViewHeight+rowSpace;
for(int i=0;i<totalCells;i++){
//获取列索引
int col=i%colums;
//获取行索引
int rows=i/colums;
CGRect frame=CGRectMake(leftSpace+col*hspace, topSpace+rows*vspace, kViewWidth, kViewHeight);
[self.frameArray addObject:[NSValue valueWithCGRect:frame]];
}
NSValue *frameValue=[self.frameArray lastObject] ;
CGRect frame=[frameValue CGRectValue];
NSValue *frameValue2=self.frameArray[colums-1] ;
CGRect frame2=[frameValue2 CGRectValue];
CGFloat screenWidth = CGRectGetMaxX(frame2)+rightSpace;
self.contentSize=CGSizeMake(screenWidth, CGRectGetMaxY(frame));
self.showsVerticalScrollIndicator=NO;
}
-(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) {
if (!self.inDic[@(i)]) {
UIView * view=[self.jrDatasource jrsCroll:self cellAtIndex:i];
view.frame=frame;
[self addSubview:view];
[self.inDic setObject:view forKey:@(i)];
}
}else{
JRCellView * jrcell=self.inDic[@(i)];
if (jrcell){
//加入缓存池
NSMutableSet * set=self.poolDic[jrcell.identy];
[set addObject:jrcell];
[jrcell removeFromSuperview];
[self.inDic removeObjectForKey:@(i)];
}
}
}
}
#pragma mark - 判断是不是在屏幕
- (BOOL) _isInscreen:(CGRect) frame{
CGFloat contentY=self.contentOffset.y;
CGFloat contentX=self.contentOffset.x;
BOOL condition1= CGRectGetMaxY(frame)>contentY && frame.origin.y<contentY+self.frame.size.height;
BOOL condition2= CGRectGetMaxX(frame)>contentX && frame.origin.x<contentX+self.frame.size.width;
return condition1 && condition2;
}
#pragma mark - 重复利用
//获取可重复利用cell
- (JRCellView *)dequeueReusedCellWithIdenty:(NSString *) identy{
//初始化池子
NSMutableSet * set=self.poolDic[identy];
if(set==nil){
set=[NSMutableSet set];
[self.poolDic setObject:set forKey:identy];
}
//如果cell被引用了,需要从池子里面删除
JRCellView * view=[set anyObject];
if (view!=nil) {
[set removeObject:view];
}
return view ;
}
//*******
- (void) loadDatas{
[self _addSubviews];
}
@end