UITableview 上提刷新
最近做的项目中用到了列表,数据是要从webservice请求,网络是通过3G或者Wifi来连接,所以决定采用分页加载方式下载数据。
从网上找到的资料,基本思路就是在Tableview的末尾,也就是contentview(Tableview本身继承与Scrollview)的末尾,加一个footview,用来显示:“上拉加载更多数据”、“加载中“、"松开即加载数据"。
这里个人认为比较重要的思想就是tableview与footview之间的交互。分以下三个步骤吧:
1.tableview需要通知footview的事情包括滑动,还有滑动结束。
2.footview对于滑动的相应:询问tableview是否正在加载更多数据,更新显示的标题。
3.footview对于滑动结束的相应:通知tableview的控制器是否加载更多数据。
4.tableview加载更多数据去,加载完毕再回头通知footview
不知这样说能否明白,我暂时是这么理解的。下面根据1-3步骤来说下代码。
要实现步骤1:
/*TableViewController.m*/ //UIScrollViewDeleagete Methods 1 - (void)scrollViewDidScroll:(UIScrollView *)scrollView 2 { 3 [footview RefreshScrollViewDidScroll:scrollView];//只要滑动就会触发,这时候要通知footview 4 } 5 6 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 7 { 8 [footview RefreshScrollViewDidEndDragging:scrollView];//滑动结束,通知footview 9 } //这段代码是tableview的控制器中,要实现通知footview滑动消息的两个委托方法。
footview得知滑动消息后,要作出反应。
实现步骤2:
//Footview.m 1 //手指屏幕上不断拖动调用此方法 2 - (void)RefreshScrollViewDidScroll:(UIScrollView *)scrollView { 3 4 if (_state == PullRefreshLoading) {//footview显示“正在加载”状态 5 6 CGFloat offset = MAX(scrollView.contentOffset.y * -1, 0); 7 offset = MIN(offset, 60); 8 scrollView.contentInset = UIEdgeInsetsMake(0.0, 0.0f, RefreshViewHight, 0.0f);//将表格数据提上去,为footview腾出空间 9 10 } else if (scrollView.isDragging) {//拖动,但是没有松开,这个时候需要根据拖动的距离显示"上拉加载更多数据"或者“松开即可加载更多” 11 12 BOOL _loading = NO; 13 if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDataSourceIsLoading:)]) { 14 _loading = [_delegate RefreshTableHeaderDataSourceIsLoading:self];//从tableview获取是不是正在加载更多数据,如果是的话,那么footview将不做出反应,也就是说,保证每次只加载一次数据 15 } 16 17 if (_state == EGOOPullRefreshPulling && scrollView.contentOffset.y + (scrollView.frame.size.height) < scrollView.contentSize.height + RefreshViewHight && scrollView.contentOffset.y > 0.0f && !_loading) { 18 [self setState:PullRefreshNormal];//footview显示"上拉将加载更多" 19 } else if (_state == EGOOPullRefreshNormal && scrollView.contentOffset.y + (scrollView.frame.size.height) > scrollView.contentSize.height + RefreshViewHight && !_loading) { 20 [self setState:PullRefreshPulling];//footview显示"松开即加载更多" 21 } 22 23 if (scrollView.contentInset.bottom != 0) {//将表格恢复,将看不到footview 24 scrollView.contentInset = UIEdgeInsetsZero; 25 } 26 27 } 28 29 }
步骤3.
32 //当用户停止拖动,并且手指从屏幕中拿开的的时候调用此方法 33 - (void)RefreshScrollViewDidEndDragging:(UIScrollView *)scrollView { 34 35 BOOL _loading = NO; 36 if ([_delegate respondsToSelector:@selector(RefreshTableHeaderDataSourceIsLoading:)]) { 37 _loading = [_delegate RefreshTableHeaderDataSourceIsLoading:self];//询问tableview是否正在加载数据 38 } 39 //如果拖动的距离大于footview的高度,并且没有正在加载数据 40 if (scrollView.contentOffset.y + (scrollView.frame.size.height) > scrollView.contentSize.height + RefreshViewHight && !_loading) { 41 42 if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDidTriggerRefresh:)]) { 43 [_delegate RefreshTableHeaderDidTriggerRefresh:self];//通知tableview去加载更多数据 44 } 45 46 [self setState:PullRefreshLoading];//footview状态更改为”正在加载“ 47 [UIView beginAnimations:nil context:NULL]; 48 [UIView setAnimationDuration:0.2]; 49 scrollView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, RefreshViewHight, 0.0f); 50 [UIView commitAnimations]; 51 52 } 53 }
步骤4.
//tableview.m 实现的footview要求的协议方法 1 - (void)RefreshTableHeaderDidTriggerRefresh:(RefreshTableHeaderView*)view{ 2 3 [self reloadTableViewDataSource];//加载数据 4 [self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:4.0];//加载完毕 5 6 } 7 8 - (BOOL)RefreshTableHeaderDataSourceIsLoading:(RefreshTableHeaderView*)view{ 9 10 return _reloading; // should return if data source model is reloading 11 12 }
1 - (void)reloadTableViewDataSource{ 2 3 // 在这里加载更多数据 4 // put here just for demo 5 _reloading = YES; 6 7 } 8 9 - (void)doneLoadingTableViewData{ 10 11 // model should call this when its done loading 12 _reloading = NO; 13 [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];//加载完毕后通知footview 14 15 }
这样描述下来可能比较抽象,总结一下:
footview要做的事情:
从tableview索取滑动信息,更新自己的状态;(“上拉更新数据”,“松开即加载数据”)
从tableview索取滑动信息,如果需要更新,那么更新自己状态(“正在加载数据”),再通知tableview去更新数据;
从tableview获取加载完毕的消息,更新自己状态(“上拉提取更多数据")
tableview要做的事情:
通知footview滑动的信息;
被通知加载数据;
参考代码在这里:
http://www.cocoachina.com/bbs/job.php?action=download&aid=26207