在IOS開發中UITableView是很是經常使用的一個功能,而在使用UITableView的時候咱們常常要用到下拉刷新和上拉加載的功能,今天花時間實現了簡單的UITableView的下拉刷新和上拉加載功能,效果圖以下:async
代碼以下:ide
TableRefreshHeaderView.hatom
#import <UIKit/UIKit.h> @interface TableRefreshHeaderView : UIView @property(nonatomic, strong)UIImageView *arrowView; @property(nonatomic, strong)UILabel *refreshText; @property(nonatomic, strong)UIActivityIndicatorView *loadingIndicatorView; -(instancetype)initWithFrame:(CGRect)frame; - (void)setRefreshMode:(int)mode; @end
TableRefreshHeaderView.mspa
#import "TableRefreshHeaderView.h" #define UISCREEN_WIDTH [UIScreen mainScreen ].bounds.size.width #define UISCREEN_HEIGHT [UIScreen mainScreen ].bounds.size.height @implementation TableRefreshHeaderView /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ -(instancetype)initWithFrame:(CGRect)frame; { self = [super initWithFrame:frame]; if (self) { [self addSubview:self.arrowView]; [self addSubview:self.refreshText]; [self addSubview:self.loadingIndicatorView]; self.loadingIndicatorView.hidden = YES; } return self; } //箭頭圖片UIImageView -(UIImageView *)arrowView { if (!_arrowView) { _arrowView = [[UIImageView alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - 60, 0, 15, 30)]; _arrowView.image = [UIImage imageNamed:@"arrow"]; } return _arrowView; } //下拉刷新文字 -(UILabel *)refreshText { if (!_refreshText) { _refreshText = [[UILabel alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - 15, 0, 75, 30)]; _refreshText.font = [UIFont fontWithName:@"Arial" size:14]; _refreshText.textColor = [UIColor blackColor]; _refreshText.text = @"下拉刷新"; } return _refreshText; } //刷新旋轉視圖 - (UIActivityIndicatorView *)loadingIndicatorView { if (!_loadingIndicatorView) { _loadingIndicatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - 65, 2, 25, 25)]; [_loadingIndicatorView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray]; _loadingIndicatorView.backgroundColor = [UIColor clearColor]; _loadingIndicatorView.center = CGPointMake(UISCREEN_WIDTH / 2.0 - 52, 14); } return _loadingIndicatorView; } //設置三種刷新模式 - (void)setRefreshMode:(int)mode { switch (mode) { case 1://下拉過程當中 { self.arrowView.hidden = NO; self.loadingIndicatorView.hidden = YES; [self.loadingIndicatorView stopAnimating]; [UIView animateWithDuration:0.3 animations:^(void){ _arrowView.transform = CGAffineTransformMakeRotation(M_PI * 2); }]; self.refreshText.text = @"下拉刷新"; } break; case 2://提示鬆開刷新 { self.arrowView.hidden = NO; self.loadingIndicatorView.hidden = YES; [self.loadingIndicatorView stopAnimating]; [UIView animateWithDuration:0.3 animations:^(void){ _arrowView.transform = CGAffineTransformMakeRotation(M_PI); }]; self.refreshText.text = @"鬆開刷新"; } break; case 3://鬆開後刷新 { self.arrowView.hidden = YES; self.loadingIndicatorView.hidden = NO; [self.loadingIndicatorView startAnimating]; self.refreshText.text = @"正在刷新"; } break; default: break; } } @end
TableRefreshFooterView.h.net
#import <UIKit/UIKit.h> @interface TableRefreshFooterView : UIView @property(nonatomic, strong) UIActivityIndicatorView *loadingIndcatorView; @property(nonatomic, strong) UILabel *loadingText; - (void)setLoadingMode:(int)mode; @end
TableRefreshFooterView.mcode
#import "TableRefreshFooterView.h" #define UISCREEN_WIDTH [UIScreen mainScreen ].bounds.size.width #define UISCREEN_HEIGHT [UIScreen mainScreen ].bounds.size.height @implementation TableRefreshFooterView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self addSubview:self.loadingIndcatorView]; [self addSubview:self.loadingText]; } return self; } - (UIActivityIndicatorView *)loadingIndcatorView { if (!_loadingIndcatorView) { _loadingIndcatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - 65, 2, 25, 25)]; [_loadingIndcatorView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray]; _loadingIndcatorView.backgroundColor = [UIColor clearColor]; _loadingIndcatorView.center = CGPointMake(UISCREEN_WIDTH / 2.0 - 52, 14); } return _loadingIndcatorView; } - (UILabel *)loadingText { if (!_loadingText) { _loadingText = [[UILabel alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - 15, 0, 75, 30)]; _loadingText.font = [UIFont fontWithName:@"Arial" size:14]; _loadingText.textColor = [UIColor blackColor]; _loadingText.text = @"加載中"; } return _loadingText; } - (void)setLoadingMode:(int)mode { switch (mode) { case 1: _loadingText.text = @"加載中"; [self.loadingIndcatorView startAnimating]; self.loadingIndcatorView.hidden = NO; break; case 2: _loadingText.text = @"加載完畢"; [self.loadingIndcatorView stopAnimating]; self.loadingIndcatorView.hidden = YES; break; default: break; } } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ @end
ViewController.horm
#import <UIKit/UIKit.h> #import "TableRefreshHeaderView.h" #import "TableRefreshFooterView.h" @interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource> { int rowCount;//行數 BOOL isLoading;//是否正在加載 BOOL isRefreshing;//是否正在刷新 int drageMode;//1爲下拉刷新,2爲上拉加載 } @property(nonatomic, strong)UITableView *myTableView; @property(nonatomic, strong)TableRefreshHeaderView *refreshHeaderView; @property(nonatomic, strong)TableRefreshFooterView *loadingFooterView; @end
ViewController.mserver
#import "ViewController.h" #define UISCREEN_WIDTH [UIScreen mainScreen ].bounds.size.width #define UISCREEN_HEIGHT [UIScreen mainScreen ].bounds.size.height @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; rowCount = 20; isLoading = NO; isRefreshing = NO; drageMode = -1; [self.view addSubview:self.myTableView]; [self.myTableView addSubview:self.refreshHeaderView]; [self.myTableView addSubview:self.loadingFooterView]; [self.myTableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)dealloc { [self.myTableView removeObserver:self forKeyPath:@"contentOffset"]; } - (UITableView *)myTableView { if (!_myTableView) { _myTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 50, UISCREEN_WIDTH, UISCREEN_HEIGHT - 50)]; _myTableView.delegate = self; _myTableView.dataSource = self; } return _myTableView; } - (TableRefreshHeaderView *)refreshHeaderView { if (!_refreshHeaderView) { _refreshHeaderView = [[TableRefreshHeaderView alloc]initWithFrame:CGRectMake(0, -30, UISCREEN_WIDTH, 30)]; } return _refreshHeaderView; } - (TableRefreshFooterView *)loadingFooterView { if (!_loadingFooterView) { _loadingFooterView = [[TableRefreshFooterView alloc]initWithFrame:CGRectMake(0, self.myTableView.contentSize.height, UISCREEN_WIDTH, 30)]; } return _loadingFooterView; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return rowCount; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; } cell.textLabel.text=[NSString stringWithFormat:@"%ld",indexPath.row+1]; return cell; } -(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { //若是列表控件加載完畢且當前爲下拉加載,則將下拉加載視圖移到列表可視範圍以外 if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row && drageMode == 2){ self.myTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); } } //監聽UITableview的頂部和頭部下拉事件 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { if ([keyPath isEqualToString:@"contentOffset"] && !isLoading && !isRefreshing) { self.loadingFooterView.frame = CGRectMake(0, self.myTableView.contentSize.height, UISCREEN_WIDTH, 30); if (self.myTableView.isDragging) { if (self.myTableView.contentOffset.y > -45) { [self.refreshHeaderView setRefreshMode:1]; } else if (self.myTableView.contentOffset.y < -45) { [self.refreshHeaderView setRefreshMode:2]; } } else { if (self.myTableView.contentOffset.y < -45) { drageMode = 1; self.myTableView.contentInset = UIEdgeInsetsMake(45, 0, 0, 0); [self.refreshHeaderView setRefreshMode:3]; [self beginRefresh]; } else if (self.myTableView.contentOffset.y > self.myTableView.contentSize.height - self.myTableView.frame.size.height + 45) { drageMode = 2; if (rowCount < 50) { [self.loadingFooterView setLoadingMode:1]; [self beginLoading]; } else { [self.loadingFooterView setLoadingMode:2]; self.myTableView.contentInset = UIEdgeInsetsMake(0, 0, 45, 0); } } } } } //開始刷新 - (void)beginRefresh { dispatch_async(dispatch_get_global_queue(0, 0), ^{ isRefreshing = YES; sleep(2);//處理耗時操做 dispatch_async(dispatch_get_main_queue(), ^{ [self endRefresh];//處理完以後更新界面 }); }) ; } //中止刷新 - (void)endRefresh { [UIView animateWithDuration:0.3 animations:^{ self.myTableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); }]; [self.refreshHeaderView setRefreshMode:1]; isRefreshing = NO; } //開始加載 - (void)beginLoading { dispatch_async(dispatch_get_global_queue(0, 0), ^{ isLoading = YES; rowCount += 10; self.myTableView.contentInset = UIEdgeInsetsMake(0, 0, 45, 0); sleep(2);//處理耗時操做 dispatch_async(dispatch_get_main_queue(), ^{ [self.myTableView reloadData]; [self endLoading];//處理完以後更新界面 }); }) ; } //中止加載 - (void)endLoading { if (rowCount >= 50) { [self.loadingFooterView setLoadingMode:2]; self.myTableView.contentInset = UIEdgeInsetsMake(0, 0, 45, 0); } else { self.myTableView.contentInset = UIEdgeInsetsMake(0, 0, 45, 0); [self.loadingFooterView setLoadingMode:1]; } isLoading = NO; } @end
源碼下載地址:http://download.csdn.net/detail/lzm2625347497/9601843blog