iOS实现无限循环滚动的TableView实战教程

2020-01-20 23:09:45刘景俊

4、在子类中实现需要加工处理的代理方法


- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
 self.actualRows = [self.dataSourceInterceptor.receiver tableView:tableView numberOfRowsInSection:section];
 return self.actualRows * 3;
}

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 NSIndexPath * actualIndexPath = [NSIndexPath indexPathForRow:indexPath.row % self.actualRows inSection:indexPath.section];
 return [self.dataSourceInterceptor.receiver tableView:tableView cellForRowAtIndexPath:actualIndexPath];
}

5、在拦截器中转发消息(如果子类实现了代理方法,则转发给子类;如果子类没有实现,则转发给外部的代理)


@implementation SUTableViewInterceptor

#pragma mark - forward & response override
- (id)forwardingTargetForSelector:(SEL)aSelector {
 if ([self.middleMan respondsToSelector:aSelector]) return self.middleMan;
 if ([self.receiver respondsToSelector:aSelector]) return self.receiver;
 return [super forwardingTargetForSelector:aSelector];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
 if ([self.middleMan respondsToSelector:aSelector]) return YES;
 if ([self.receiver respondsToSelector:aSelector]) return YES;
 return [super respondsToSelector:aSelector];
}

@end

到此,自定义的TableView基本完成,整理一下思路,不难理解我们是通过拦截器将代理消息转发到子类内部,子类内部则通过外部代理提供的dataSource来拷贝成3份,来组成一个3倍于普通长度的TableView,并在其滑动时进行处理,形成可以无限循环滚动的效果。

这样,在外部看起来,使用这个TableView和普通TableView没有什么不同,但是多了一个可以循环滚动的“属性”,当然,你也可以将其封装成可设置的属性,方便切换普通模式和循环滚动模式。

下面,用这个TableView的子类来试着创建一个可以循环滚动的列表看看:


- (void)viewDidLoad {
 [super viewDidLoad];
 [self.view addSubview:self.tableView];
}

- (UITableView *)tableView {
 if(!_tableView) {
  _tableView = [[SUTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
  _tableView.delegate = self;
  _tableView.dataSource = self;
  _tableView.showsVerticalScrollIndicator = NO;
  _tableView.rowHeight = 150.0;
  [_tableView registerNib:[UINib nibWithNibName:@"LiveCell" bundle:nil] forCellReuseIdentifier:liveCellID];
 }
 return _tableView;
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 return 5;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 LiveCell * cell = [self.tableView dequeueReusableCellWithIdentifier:liveCellID];
 cell.selectionStyle = UITableViewCellSelectionStyleNone;
 cell.descLabel.text = [NSString stringWithFormat:@"第 %ld 个主播频道", indexPath.row + 1];
 return cell;
}