把ScrollView转TableView,难点应该在cell复用的实现。下面重点讲解这部分的实现。
一、定义基本变量
//_visiblePages:存当前正在显示的cell,
//_recycledPages:存回收的cell
NSMutableSet *_visiblePages, *_recycledPages;
//firstIndex:当前显示中第一个cell的索引
//lastIndex:当前显示中最后一个cell的索引
NSInteger firstIndex;
NSInteger lastIndex;
二、复用代码的实现
//复用函数
- (void)tilePages
{
NSInteger num = [self.myDelegate numOfTableView:self];
firstIndex = (NSInteger)floorf(CGRectGetMinY(self.bounds)/_cellHeight);
lastIndex = (NSInteger)floorf((CGRectGetMaxY(self.bounds)-1)/_cellHeight);
if(firstIndex<0)
firstIndex = 0;
if(firstIndex>num-1)
firstIndex = num - 1;
if(lastIndex<0)
lastIndex = 0;
if(lastIndex>num-1)
lastIndex = num - 1;
//回收
for(MyTableViewCell *page in _visiblePages)
{
if(page.index<firstIndex||page.index>lastIndex)
{
[_recycledPages addObject:page];
[page removeFromSuperview];
}
}
[_visiblePages minusSet:_recycledPages];
while (_recycledPages.count > 2) // Only keep 2 recycled pages
[_recycledPages removeObject:[_recycledPages anyObject]];
//添加新的page
for(NSInteger index = firstIndex;index<=lastIndex;index++)
{
//如果不在显示队列中,就加入新的cell
if(![self isDisplayingPageForIndex:index])
{
MyTableViewCell *page = [self dequeueRecyclePage];
if(!page)
{
page = [[MyTableViewCell alloc] init];
NSLog(@"创建新的page%ld",index);
}
[_visiblePages addObject:page];
//重新设置page的位置
[self configurePage:page forIndex:index];
if([self.myDelegate respondsToSelector:@selector(MyTableView:willDisplayCell:forIndex:)])
{
[self.myDelegate MyTableView:self willDisplayCell:page forIndex:index];
}
[self addSubview:page];
}
}
}
- (MyTableViewCell *)dequeueRecyclePage
{
MyTableViewCell *page = [_recycledPages anyObject];
if(page)
[_recycledPages removeObject:page];
return page;
}
- (BOOL)isDisplayingPageForIndex:(NSInteger)index {
for (MyTableViewCell *page in _visiblePages)
if (page.index == index) return YES;
return NO;
}
- (void)configurePage:(MyTableViewCell *)page forIndex:(NSInteger)index {
page.frame = CGRectMake(0, _cellHeight*index, self.bounds.size.width, _cellHeight);
page.index = index;
}
大体思路如下:
1、计算出firstIndex和lastIndex,用这个来确定每次显示cell的索引范围。
2、进行回收:判断显示数组_visiblePages中的每个cell,如果发现不在前面的索引范围的,都从数组中移除,并放入到回收数组_recycledPages中。
3、为了防止回收数组过大,这里控制了回收数组最多存在两个cell。
4、复用或创建新的cell:在索引firstIndex和lastIndex范围间的,但不存在_visiblePages中的cell,都是必须进行复用或创建。回收数组如果还有cell,就直接复用,如果没有,就得创建新的cell。把新的cell添加到_visiblePages中,并把这个cell调整为正确的位置。
5、在每次滑动scrollView的时候,都重复执行上面的复用函数。
我只是进行了一个简单的实现,包括每个cell的高度我都定死了,复用只用于同一类型的cell。当然你们可以在这个基础上进行拓展,把它实现得跟系统的UITableView类似。
网友评论