想法
前端时间在一些应用中(facebook,支付宝,简书等)经常会看到类似下图的样子,在tableview
列表请求数据时显示的一些默认单元格,看起来我觉得还不错,于是想自己写一个比较通用一点的。
我的想法是请求之前,在
tableView
的dataSource
协议numberOfRowsInSection:
中返回固定的个数,请求之后在返回数据源的个数;同理在cellForTableView:
这个协议中也是一样。
不过这样做起来相对比较麻烦,如果需求上有很多列表页都要这样的效果,那就要每个页面都要进行判断,成本比较高。
后来我想,不如直接将上图那个视图当作tableview
的空白页来显示,然后通过委托模式来给受委托者来处理。这样一来,对于这种效果,就避免了每次都要进行判断,也一定程度上实现了代码的解耦。
代码
1.设置空白代理
- (void)setupTableView {
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.emptyCellDataSource = self;
_tableView.emptyCellDelegate = self;
[_tableView reloadData];
[_tableView reloadEmptyDataSource];
}
2.实现协议方法
#pragma mark - UITableViewEmptyCellDataSource -
- (NSInteger)tableView:(UITableView *)tableView numberOfUITableViewEmptyCellInSection:(NSInteger)section {
return floor(self.view.bounds.size.height/70.0);
}
- (UITableViewCell * _Nonnull)cellForTableView:(UITableView *)tableView {
return [EmptyCell cellWithTableView:tableView];
}
#pragma mark - UITableViewEmptyCellDelegate -
- (CGFloat)heightForEmptyCellAtIndexPath:(NSIndexPath *)indexPath {
return 70.0;
}
3.获取数据时刷新空白页
- (void)fetchData {
[self.datasource removeAllObjects];
[self.view addSubview:self.activityIndicatorView];
[_activityIndicatorView startAnimating];
for (int i=0; i<22; i++) {
[self.datasource addObject:@(i)];
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_activityIndicatorView stopAnimating];
[_activityIndicatorView removeFromSuperview];
[_tableView reloadData];
[_tableView reloadEmptyDataSource];
});
}
总结
代码可能还有很多不完善的地方,希望多多提意见。如果对于这种效果有更好的想法的,希望能留言分享下,小弟不甚感激。
本Demo地址:https://github.com/Cherishforever/UTEmptyCellTableView