在使用tablevie的应用中基本上都会使用下拉刷新和加载更多,所以掌握这两个效果的实现是很有必要的,在ios6中添加了UIrefreshControl为表视图控制器增加了下拉刷新功能,而之前的版本就只能使用第三方的了,EGO团队的开源代码就不错 ,可以使用一下代码初始化
if(NSClassFromString(@"UIRefreshControl")) {
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(refreshedByPullingTable:) forControlEvents:UIControlEventValueChanged];
} else {
self.refreshHeaderView = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.tableView.bounds.size.width, self.tableView.bounds.size.height)];
self.refreshHeaderView.keyNameForDataStore = [NSString stringWithFormat:@"%@_LastRefresh", [self class]];
self.tableView.showsVerticalScrollIndicator = YES;
[self.tableView addSubview:self.refreshHeaderView];
}
当下拉到临界点时controller会处理UIScrollView 的委托,在UITableView视图顶部增加一个EGORefreshHeaderView视图,记住最后的状态保存到某个键中 实现代码如下
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if(self.searchDisplayController.searchResultsTableView == scrollView) return;
if (self.refreshHeaderView.state == EGOOPullRefreshLoading) {
CGFloat offset = MAX(scrollView.contentOffset.y * -1, 0);
offset = MIN(offset, 60);
scrollView.contentInset = UIEdgeInsetsMake(offset, 0.0f, 0.0f, 0.0f);
}
else if (scrollView.isDragging) {
if (self.refreshHeaderView.state == EGOOPullRefreshPulling && scrollView.contentOffset.y > -65.0f && scrollView.contentOffset.y < 0.0f && !self.loading) {
[self.refreshHeaderView setState:EGOOPullRefreshNormal];
}
else if (self.refreshHeaderView.state == EGOOPullRefreshNormal && scrollView.contentOffset.y < -65.0f && !self.loading) {
[self.refreshHeaderView setState:EGOOPullRefreshPulling];
}
if (scrollView.contentInset.top != 0) {
scrollView.contentInset = UIEdgeInsetsZero;
}
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(self.searchDisplayController.searchResultsTableView == scrollView) return;
if (scrollView.contentOffset.y <= - 65.0f && !self.loading) {
self.loading = YES;
[self.refreshHeaderView setState:EGOOPullRefreshLoading];
[self.tableView reloadData];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
self.tableView.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);
[UIView commitAnimations];
[self doRefresh];
}
}
-(void) refreshedByPullingTable:(id) sender {
[self.refreshControl beginRefreshing];
[self doRefresh];
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.refreshControl endRefreshing];
});
}
-(void) doRefresh
{
NSLog(@"Override doRefresh in subclass. This line should not appear on console");
}
-(void) loadMore {
NSLog(@"Override loadMore in subclass. This line should not appear on console");
}
-(void) setLoading:(BOOL)loading
{
_loading = loading;
[UIView beginAnimations:nil context:NULL];
if(loading)
{
[self.refreshHeaderView setState:EGOOPullRefreshLoading];
[UIView setAnimationDuration:0.2];
self.tableView.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);
}
else
{
[self.refreshHeaderView setState:EGOOPullRefreshNormal];
[self.refreshHeaderView setCurrentDate];
[UIView setAnimationDuration:.3];
[self.tableView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];
}
[UIView commitAnimations];
}
其中dorefesh和loadMore需要在子类中实现
加载更多 在loadMore中实现 当用户到达表视图当前页面时的底部时调用
-(void) loadMore {
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
self.pageCount ++;
if(self.pageCount == 5) self.endReached = YES;
[self.tableView reloadData];
});
}
每次加载20条数据 在子类中实现下拉刷新与加载更多 在父类中实现表视图更新 应该还有更好的解决方案