首先,用到一个开源框架,可以去https://github.com/enormego/EGOTableViewPullRefresh下载。
然后,将里面的EGORefreshTableHeaderView.h和EGORefreshTableHeaderView.m拷到相应的项目里,在需要下拉刷新的页面对应的视图控制器中添加以下代码。
头文件:
- #import "EGORefreshTableHeaderView.h"
- @interface RootViewController : UITableViewController <EGORefreshTableHeaderDelegate, UITableViewDelegate, UITableViewDataSource>{
- EGORefreshTableHeaderView *_refreshHeaderView;
- BOOL _reloading;
- }
- - (void)reloadTableViewDataSource;
- - (void)doneLoadingTableViewData;
- @end
实现文件:
- #import "RootViewController.h"
- @implementation RootViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- if (_refreshHeaderView == nil) {
- EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
- view.delegate = self;
- [self.tableView addSubview:view];
- _refreshHeaderView = view;
- [view release];
- }
- [_refreshHeaderView refreshLastUpdatedDate];
- }
- #pragma mark -
- #pragma mark UITableViewDataSource
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return 10;
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return 4;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *CellIdentifier = @"Cell";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
- }
- return cell;
- }
- - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
- return [NSString stringWithFormat:@"Section %i", section];
- }
- #pragma mark -
- #pragma mark Data Source Loading / Reloading Methods
- - (void)reloadTableViewDataSource{
- _reloading = YES;
- }
- - (void)doneLoadingTableViewData{
- _reloading = NO;
- [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
- }
- #pragma mark -
- #pragma mark UIScrollViewDelegate Methods
- - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
- [_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
- }
- - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
- [_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
- }
- #pragma mark -
- #pragma mark EGORefreshTableHeaderDelegate Methods
- - (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
- [self reloadTableViewDataSource];
- [self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];
- }
- - (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{
- return _reloading;
- }
- - (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{
- return [NSDate date];
- }
- #pragma mark -
- #pragma mark Memory Management
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- }
- - (void)viewDidUnload {
- _refreshHeaderView=nil;
- }
- - (void)dealloc {
- _refreshHeaderView = nil;
- [super dealloc];
- }
- @end
最后,一个很重要的步骤,别忘了加入QuartzCore.framework框架。
上文的实现中有个这样的方法:
- - (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
- [self reloadTableViewDataSource];
- [self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];
- }
显然,这是有问题的。当触发刷新的时候,我们需要和服务端进行交互,这时就会执行这个代理方法,首先调用了reloadTableViewDataSource,表示要和服务端进行交互了,此时_reloading值为YES,3秒后又调用了doneLoadingTableViewData,从而结束刷新效果的显示,我们实际上是假设这时候服务端已经正常将数据发送到客户端来了。事实上,实际收到服务端的数据所用的时间是不确定的,所以,应该在数据返回后再结束刷新效果。
- - (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
- [self reloadTableViewDataSource];
- //发送异步请求的代码
- }
- - (void)requestFinished:(ASIHTTPRequest *)request {
- [self doneLoadingTableViewData];
- }