UITableView继承UIScrollView; 所以首先来学习下UIScrollView的一些属性和方法.
scrollView1.contentOffset = CGPointMake(100,0);
可以用来控制UIScrollView的显示位置;
当contentOffset改变的时候会调用:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
当手离开屏幕时, 停止拖拽的时候会调用.
@interface PullRefreshTableViewController :UITableViewController {
UIView *refreshHeaderView;
UILabel *refreshLabel;
UIImageView *refreshArrow;
UIActivityIndicatorView *refreshSpinner;
BOOL isDragging;
BOOL isLoading;
NSString *textPull;
NSString *textRelease;
NSString *textLoading;
}
@property (nonatomic,retain)UIView *refreshHeaderView;
@property (nonatomic,retain)UILabel *refreshLabel;
@property (nonatomic,retain)UIImageView *refreshArrow;
@property (nonatomic,retain)UIActivityIndicatorView *refreshSpinner;
@property (nonatomic,copy)NSString *textPull;
@property (nonatomic,copy)NSString *textRelease;
@property (nonatomic,copy)NSString *textLoading;
- (void)addPullToRefreshHeader;
- (void)startLoading;
- (void)stopLoading;
- (void)refresh;
@end
#define REFRESH_HEADER_HEIGHT52.0f
@implementation PullRefreshTableViewController
@synthesize textPull, textRelease, textLoading, refreshHeaderView, refreshLabel, refreshArrow, refreshSpinner;
- (id)initWithStyle:(UITableViewStyle)style {
self = [superinitWithStyle:style];
if (self != nil) {
textPull = [[NSStringalloc]initWithString:@"Pull down to refresh..."];
textRelease = [[NSStringalloc]initWithString:@"Release to refresh..."];
textLoading = [[NSStringalloc]initWithString:@"Loading..."];
}
returnself;
}
- (void)viewDidLoad {
[superviewDidLoad];
[selfaddPullToRefreshHeader];
}
- (void)addPullToRefreshHeader {
//
refreshHeaderView = [[UIViewalloc]initWithFrame:CGRectMake(0,0 -REFRESH_HEADER_HEIGHT,320,REFRESH_HEADER_HEIGHT)];
refreshHeaderView.backgroundColor = [UIColorclearColor];
refreshLabel = [[UILabelalloc]initWithFrame:CGRectMake(0,0,320,REFRESH_HEADER_HEIGHT)];
refreshLabel.backgroundColor = [UIColorclearColor];
refreshLabel.font = [UIFontboldSystemFontOfSize:12.0];
refreshLabel.textAlignment = UITextAlignmentCenter;
refreshArrow = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"arrow.png"]];
refreshArrow.frame = CGRectMake((REFRESH_HEADER_HEIGHT - 27) /2,
(REFRESH_HEADER_HEIGHT -44) /2,
27,44);
refreshSpinner = [[UIActivityIndicatorViewalloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
refreshSpinner.frame = CGRectMake((REFRESH_HEADER_HEIGHT - 20) /2, (REFRESH_HEADER_HEIGHT - 20) /2,20,20);
refreshSpinner.hidesWhenStopped = YES;
[refreshHeaderViewaddSubview:refreshLabel];
[refreshHeaderViewaddSubview:refreshArrow];
[refreshHeaderViewaddSubview:refreshSpinner];
[self.tableViewaddSubview:refreshHeaderView];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
if (isLoading)return;
isDragging = YES;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (isLoading) {
// Update the content inset, good for section headers
if (scrollView.contentOffset.y > 0)
self.tableView.contentInset = UIEdgeInsetsZero;
elseif (scrollView.contentOffset.y >= -REFRESH_HEADER_HEIGHT)
self.tableView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y,0,0,0);
}elseif (isDragging && scrollView.contentOffset.y < 0) {
// Update the arrow direction and label
[UIViewbeginAnimations:nilcontext:NULL];
if (scrollView.contentOffset.y < -REFRESH_HEADER_HEIGHT) {
//改变文字和图片
refreshLabel.text = self.textRelease;
[refreshArrowlayer].transform = CATransform3DMakeRotation(M_PI,0,0,1);
}else {// User is scrolling somewhere within the header
refreshLabel.text = self.textPull;
[refreshArrowlayer].transform =CATransform3DMakeRotation(M_PI * 2,0,0,1);
}
[UIViewcommitAnimations];
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
//这里是用户拖动,所以放开后只会进来一次
if (isLoading)return;
isDragging = NO;
// contentOffset表示上面的内容变成可见了,默认的是contentOffset为CGPointZero
if (scrollView.contentOffset.y <= -REFRESH_HEADER_HEIGHT) {
// Released above the header
[selfstartLoading];
}
}
- (void)startLoading {
isLoading = YES;
// Show the header
[UIViewbeginAnimations:nilcontext:NULL];
[UIViewsetAnimationDuration:0.3];
self.tableView.contentInset = UIEdgeInsetsMake(REFRESH_HEADER_HEIGHT,0,0,0);
refreshLabel.text = self.textLoading;
refreshArrow.hidden = YES;
[refreshSpinnerstartAnimating];
[UIViewcommitAnimations];
// Refresh action!
[selfrefresh];
}
- (void)stopLoading {
isLoading = NO;
// Hide the header
[UIViewbeginAnimations:nilcontext:NULL];
[UIViewsetAnimationDelegate:self];
[UIViewsetAnimationDuration:0.3];
[UIViewsetAnimationDidStopSelector:@selector(stopLoadingComplete:finished:context:)];
self.tableView.contentInset = UIEdgeInsetsZero;
[refreshArrowlayer].transform = CATransform3DMakeRotation(M_PI * 2,0,0,1);
[UIViewcommitAnimations];
}
- (void)stopLoadingComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
// Reset the header
refreshLabel.text = self.textPull;
refreshArrow.hidden = NO;
[refreshSpinnerstopAnimating];
}
- (void)refresh {
// This is just a demo. Override this method with your custom reload action.
// Don't forget to call stopLoading at the end.
[selfperformSelector:@selector(stopLoading)withObject:nilafterDelay:2.0];
}