也许是过去的一段时间一直很忙,今天把过去的一些东西总结总结。 发几片菜鸟博客装装X。
一直在开发,经常会用到TableView的拉提刷新操作(iOS6以下的版本。 iOS6+的用苹果自己的)。 网上有很多版本,大同小异。不过用的过程中都比较繁琐(个人意见)。
所以自己稍微做了点修改,以尽可能自己用的方便。
自己在使用TableView的时候不怎么喜欢子类化UITableViewController,一般都直接AddSubView 所以这套使用方式是按照我的代码习惯来的。
不废话,直接上代码:
RefreshTableView.h
//
// RefreshTableView.h
// TableViewRefresh
//
// Created by 王 尧 on 13-5-18.
//
//
#import <UIKit/UIKit.h>
#import "EGORefreshTableHeaderView.h"
#import "EGORefreshTableFooterView.h"
#import "EGOViewCommon.h"
@protocol RefreshTableViewDelegate <NSObject>
/**
* @desc TODO: 触发操作-->下拉刷新
* @author Wangyao
* @param N/A
* @return N/A
* @since N/A
*/
- (void)beginLoadData_PullDown;
/**
* @desc TODO: 触发操作-->上拉刷新
* @author Wangyao
* @param N/A
* @return N/A
* @since N/A
*/
- (void)beginLoadData_PullUp;
@end
@interface RefreshTableView : UITableView
{
BOOL _reloading;
}
@property (nonatomic, retain) EGORefreshTableHeaderView *refreshHeaderView;
@property (nonatomic, retain) EGORefreshTableFooterView *refreshFooterView;
//用来告知调用类需要执行刷新回调-->不实现该回调的统统切JJ
@property (nonatomic, assign) id<RefreshTableViewDelegate> pullActionDelegate;
/**
* @desc TODO: 配置是否显示头部及底部的刷新栏
* @author Wangyao
* @param N/A
* @return N/A
* @since N/A
*/
- (void)configHeaderUsing:(BOOL)useHeader footer:(BOOL)useFooter;
// create/remove footer/header view, reset the position of the footer/header views
-(void)setFooterView;
-(void)removeFooterView;
-(void)createHeaderView;
-(void)removeHeaderView;
// overide methods
-(void)beginToReloadData:(EGORefreshPos)aRefreshPos;
-(void)finishReloadingData;
// force to refresh
-(void)showRefreshHeader:(BOOL)animated;
@end
RefreshTableView.m
//
// RefreshTableView.m
// TableViewRefresh
//
// Created by 王 尧 on 13-5-18.
//
//
#import "RefreshTableView.h"
@interface RefreshTableView ()<EGORefreshTableDelegate,UIScrollViewDelegate>
@end
@implementation RefreshTableView
- (void)dealloc{
if (_refreshHeaderView) {
[_refreshHeaderView release];
_refreshHeaderView = nil;
}
if (_refreshFooterView) {
[_refreshFooterView release];
_refreshFooterView = nil;
}
self.pullActionDelegate = nil;
[super dealloc];
}
- (void)configRefreshTableView{
self.contentInset = UIEdgeInsetsMake(0, 0, 10.0, 0);
// set header
}
/**
* @desc TODO: 配置是否显示头部及底部的刷新栏
* @author Wangyao
* @param N/A
* @return N/A
* @since N/A
*/
- (void)configHeaderUsing:(BOOL)useHeader footer:(BOOL)useFooter{
if (useHeader) {
[self createHeaderView];
}
if (useFooter) {
[self setFooterView];
}
}
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
self = [super initWithFrame:frame style:style];
if (self) {
[self configRefreshTableView];
}
return self;
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self configRefreshTableView];
}
return self;
}
- (void)awakeFromNib{
[self configRefreshTableView];
}
#pragma mark-==============================上拉 下拉 刷新 ======================
#pragma mark
#pragma methods for creating and removing the header view
-(void)createHeaderView{
if (_refreshHeaderView && [_refreshHeaderView superview]) {
[_refreshHeaderView removeFromSuperview];
}
_refreshHeaderView = [[EGORefreshTableHeaderView alloc] initWithFrame:
CGRectMake(0.0f, 0.0f - self.bounds.size.height,
self.frame.size.width, self.bounds.size.height)];
_refreshHeaderView.delegate = self;
[self addSubview:_refreshHeaderView];
[_refreshHeaderView refreshLastUpdatedDate];
}
-(void)removeHeaderView{
if (_refreshHeaderView && [_refreshHeaderView superview]) {
[_refreshHeaderView removeFromSuperview];
}
_refreshHeaderView = nil;
}
-(void)setFooterView{
// if the footerView is nil, then create it, reset the position of the footer
CGFloat height = MAX(self.contentSize.height, self.frame.size.height);
if (_refreshFooterView && [_refreshFooterView superview]) {
// reset position
_refreshFooterView.frame = CGRectMake(0.0f,
height,
self.frame.size.width,
self.bounds.size.height);
}else {
// create the footerView
_refreshFooterView = [[EGORefreshTableFooterView alloc] initWithFrame:
CGRectMake(0.0f, height,
self.frame.size.width, self.bounds.size.height)];
_refreshFooterView.delegate = self;
[self addSubview:_refreshFooterView];
}
if (_refreshFooterView) {
[_refreshFooterView refreshLastUpdatedDate];
}
}
-(void)removeFooterView{
if (_refreshFooterView && [_refreshFooterView superview]) {
[_refreshFooterView removeFromSuperview];
}
_refreshFooterView = nil;
}
#pragma mark-
#pragma mark force to show the refresh headerView
-(void)showRefreshHeader:(BOOL)animated{
if (animated)
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
self.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);
// scroll the table view to the top region
[self scrollRectToVisible:CGRectMake(0, 0.0f, 1, 1) animated:NO];
[UIView commitAnimations];
}
else
{
self.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);
[self scrollRectToVisible:CGRectMake(0, 0.0f, 1, 1) animated:NO];
}
[_refreshHeaderView setState:EGOOPullRefreshLoading];
}
#pragma mark -
#pragma mark data reloading methods that must be overide by the subclass
-(void)beginToReloadData:(EGORefreshPos)aRefreshPos{
// should be calling your tableviews data source model to reload
_reloading = YES;
if (aRefreshPos == EGORefreshHeader) {
// pull down to refresh data
// overide, the actual loading data operation is done in the subclass
//下拉刷新
if (self.pullActionDelegate && [self.pullActionDelegate respondsToSelector:@selector(beginLoadData_PullDown)]) {
[self.pullActionDelegate performSelector:@selector(beginLoadData_PullDown)];
}
}else if(aRefreshPos == EGORefreshFooter){
// pull up to load more data
if (self.pullActionDelegate && [self.pullActionDelegate respondsToSelector:@selector(beginLoadData_PullUp)]) {
//上拉刷新
[self.pullActionDelegate performSelector:@selector(beginLoadData_PullUp)];
}
}
}
#pragma mark -
#pragma mark method that should be called when the refreshing is finished
- (void)finishReloadingData{
// model should call this when its done loading
_reloading = NO;
if (_refreshHeaderView) {
[_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self];
}
if (_refreshFooterView) {
[_refreshFooterView egoRefreshScrollViewDataSourceDidFinishedLoading:self];
[self setFooterView];
}
// overide, the actula reloading tableView operation and reseting position operation is done in the subclass
}
#pragma mark -
#pragma mark EGORefreshTableDelegate Methods
- (void)egoRefreshTableDidTriggerRefresh:(EGORefreshPos)aRefreshPos{
[self beginToReloadData:aRefreshPos];
}
- (BOOL)egoRefreshTableDataSourceIsLoading:(UIView*)view{
return _reloading; // should return if data source model is reloading
}
// if we don't realize this method, it won't display the refresh timestamp
- (NSDate*)egoRefreshTableDataSourceLastUpdated:(UIView*)view{
return [NSDate date]; // should return date data source was last changed
}
@end
使用:
重点:在初始化TableView后 一定要调用配置函数:
[self.infoTableView configHeaderUsing:YES footer:YES];
self.infoTableView.pullActionDelegate = self;
设置是否使用上拉 HeaderUsing 是否使用下拉 footer 设置上拉下拉的代理 pullActionDelegate
self.infoTableView = [[[RefreshTableView alloc] initWithFrame:self.bounds style:UITableViewStylePlain] autorelease];
[self.infoTableView configHeaderUsing:YES footer:YES];
[self.infoTableView setBackgroundColor:[UIColor clearColor]];
self.infoTableView.delegate = self;
self.infoTableView.dataSource = self;
self.infoTableView.pullActionDelegate = self;
[self addSubview:self.infoTableView];
实现回调:
#pragma mark-===============================UIScrollViewDelegate==================
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (self.infoTableView.refreshHeaderView) {
[self.infoTableView.refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
}
if (self.infoTableView.refreshFooterView) {
[self.infoTableView.refreshFooterView egoRefreshScrollViewDidScroll:scrollView];
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if (self.infoTableView.refreshHeaderView) {
[self.infoTableView.refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
}
if (self.infoTableView.refreshFooterView) {
[self.infoTableView.refreshFooterView egoRefreshScrollViewDidEndDragging:scrollView];
}
}
#pragma mark-==============================上拉 下拉 刷新 ======================
#pragma mark
/**
* @desc TODO: 触发操作-->下拉刷新
* @author Wangyao
* @param N/A
* @return N/A
* @since N/A
*/
- (void)beginLoadData_PullDown{
self.currentPage = -1;
[self loadListData];
}
/**
* @desc TODO: 触发操作-->上拉刷新
* @author Wangyao
* @param N/A
* @return N/A
* @since N/A
*/
- (void)beginLoadData_PullUp{
[self loadListData];
}
ok,就这样。,,
=================14年 11月 21日 修改 ==================================
之前的代码存在bug。 今天难得有空, 把一年前的代码拿出来,重新改了改。
先的下载地址如下:
源码下载: 点击打开链接 http://download.csdn.net/detail/stackhero/8182673