实际开发中,一个非常常见的场景是UITableView
的分页加载,滑动到底部时自动加载更多,大部分开发者的解决方案是监听UIScrollView
的滑动事件,判断滑动到底部时加载下一页数据,同时为UITableView addTableFooterView
以展示一个loading的效果(一般是放一个UIActivityIndicatorView
)。
这种做法有两个缺点:
- 当加载完成显示新数据时,新的Cell会替代footer的位置,出现跳动的现象,给人的直接感觉是会“卡顿”一下,很影响体验;
- 这种方式必须在
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
中判断当前的偏移量以决定什么时机开始加载下一页,这无疑增加了复杂度。
一个更好的解决方案是把loading more作为一个Cell,而不是footer,这样,以上两个问题就可以完全避免了。
Talk is cheap,show you code!
1 2 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]; }
|