实际开发中,一个非常常见的场景是UITableView的分页加载,滑动到底部时自动加载更多,大部分开发者的解决方案是监听UIScrollView的滑动事件,判断滑动到底部时加载下一页数据,同时为UITableView addTableFooterView以展示一个loading的效果(一般是放一个UIActivityIndicatorView)。
这种做法有两个缺点:
- 当加载完成显示新数据时,新的Cell会替代footer的位置,出现跳动的现象,给人的直接感觉是会“卡顿”一下,很影响体验;
- 这种方式必须在- (void)scrollViewDidScroll:(UIScrollView *)scrollView中判断当前的偏移量以决定什么时机开始加载下一页,这无疑增加了复杂度。
一个更好的解决方案是把loading more作为一个Cell,而不是footer,这样,以上两个问题就可以完全避免了。
Talk is cheap,show you code!
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 
 | #pragma mark - UITableView Datasource
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
 {
 if (_datasource.count && _hasMore)
 {
 return 2;
 }
 
 return 1;
 }
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
 if (section == 0)
 {
 return _datasource.count;
 }
 
 
 return 1;
 }
 
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
 if (indexPath.section == 0)
 {
 
 
 
 return cell;
 }
 
 
 static NSString *CellIdentifierLoadMore = @"CellIdentifierLoadMore";
 
 UITableViewCell *loadCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierLoadMore];
 if (!loadCell)
 {
 loadCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierLoadMore];
 loadCell.backgroundColor = [UIColor clearColor];
 loadCell.contentView.backgroundColor = [UIColor clearColor];
 
 UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
 indicator.tag = kLoadMoreIndicatorTag;
 indicator.hidesWhenStopped = YES;
 indicator.center = CGPointMake(loadCell.dt_width/2, loadCell.dt_height/2);
 indicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|
 UIViewAutoresizingFlexibleRightMargin|
 UIViewAutoresizingFlexibleTopMargin|
 UIViewAutoresizingFlexibleBottomMargin;
 [loadCell.contentView addSubview:indicator];
 }
 
 return loadCell;
 }
 
 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
 {
 if (indexPath.section == 0)
 {
 
 
 }
 
 
 return 44;
 }
 
 #pragma mark - UITableView Delegate methods
 
 - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
 {
 if (indexPath.section == 0)
 {
 return;
 }
 
 
 UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:kLoadMoreIndicatorTag];
 [indicator startAnimating];
 
 
 [self loadNextPage];
 }
 
 - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
 {
 if (indexPath.section == 0)
 {
 return;
 }
 
 
 UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:kLoadMoreIndicatorTag];
 [indicator stopAnimating];
 }
 
 |