参考文档
链接文章是天猫开源的一个异构滚动视图,并在天猫苹果端实现,其涉及高效复用,学习后简单码一下。
异构滚动视图是相对于TableView的同构滚动视图而言。普通ScrollView视图较少时不用考虑复用题,但当数量不断增加后复用就显得很必要。
STEP1.
TMMuiLazyScrollView *scrollview = [[TMMuiLazyScrollView alloc]init];
scrollview.frame = self.view.bounds;
//设置contentSize
scrollview.contentSize = CGSizeMake(CGRectGetWidth(self.view.bounds), 1230);
scrollview.dataSource = self;
[self.view addSubview:scrollview];
//Here is frame array for test.
//LazyScrollView must know every rect before rending.
//必须先设置每个Item相对于滚动视图的绝对坐标
rectArray = [[NSMutableArray alloc] init];
//单列Item
//Create a single column layout with 5 elements;
for (int i = 0; i < 5 ; i++) {
[rectArray addObject:[NSValue valueWithCGRect:CGRectMake(10, i *80 + 2 , self.view.bounds.size.width-20, 80-2)]];
}
//双列item
//Create a double column layout with 10 elements;
for (int i = 0; i < 10 ; i++) {
[rectArray addObject:[NSValue valueWithCGRect:CGRectMake((i%2)*self.view.bounds.size.width/2 + 3, 410 + i/2 *80 + 2 , self.view.bounds.size.width/2 -3, 80 - 2)]];
}
//三列item
//Create a trible column layout with 15 elements;
for (int i = 0; i < 15 ; i++) {
[rectArray addObject:[NSValue valueWithCGRect:CGRectMake((i%3)*self.view.bounds.size.width/3 + 1, 820 + i/3 *80 + 2 , self.view.bounds.size.width/3 -3, 80 - 2)]];
}
//STEP 3 reload LazyScrollView
//相当于再走一遍代理方法
[scrollview reloadData];
STEP2.
//第二步 实现代理方法
// implement datasource delegate.
- (NSUInteger)numberOfItemInScrollView:(TMMuiLazyScrollView *)scrollView
{
return rectArray.count;
}
//根据index返回rectModel
- (TMMuiRectModel *)scrollView:(TMMuiLazyScrollView *)scrollView rectModelAtIndex:(NSUInteger)index
{
CGRect rect = [(NSValue *)[rectArray objectAtIndex:index]CGRectValue];
TMMuiRectModel *rectModel = [[TMMuiRectModel alloc]init];
//两个属性,一个相对于异构视图的绝对位置,一个唯一ID
rectModel.absoluteRect = rect;
rectModel.muiID = [NSString stringWithFormat:@"%ld",index];
return rectModel;
}
//根据MuiID返回对应的view,view与rectModel数量一致
- (UIView *)scrollView:(TMMuiLazyScrollView *)scrollView itemByMuiID:(NSString *)muiID
{
//Find view that is reuseable first.
//首先取出复用的Item
LazyScrollViewCustomView *label = (LazyScrollViewCustomView *)[scrollView dequeueReusableItemWithIdentifier:@"testView"];
//索引用的标识,在异构视图中唯一
NSInteger index = [muiID integerValue];
NSLog(@"========%ld",index);
//如果不存在则新建
if (!label)
{
label = [[LazyScrollViewCustomView alloc]initWithFrame:[(NSValue *)[rectArray objectAtIndex:index] CGRectValue]];
label.textAlignment = NSTextAlignmentCenter;
label.reuseIdentifier = @"testView"; //重用ID
}
label.frame = [(NSValue *)[rectArray objectAtIndex:index]CGRectValue];
label.text = [NSString stringWithFormat:@"%lu",(unsigned long)index];
label.backgroundColor = [self randomColor];
label.userInteractionEnabled = YES;
[scrollView addSubview:label];
[label addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)]];
return label;
}
PS: GitHub 上提供的这个Demo更多地展示的是高效复用,也许是因为很少有相应的需求场景,感觉灵性有些欠缺,后期需要不断尝试实践。