在IOS开发中UITableView是非常常用的一个功能,而在使用UITableView的时候我们经常要用到下拉刷新和上拉加载的功能,今天花时间实现了简单的UITableView的下拉刷新和上拉加载功能,效果图如下:

 

  代码如下:

TableRefreshHeaderView.h

#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.m

#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 - , , , )];
_arrowView.image = [UIImage imageNamed:@"arrow"];
}
return _arrowView;
} //下拉刷新文字
-(UILabel *)refreshText
{
if (!_refreshText) {
_refreshText = [[UILabel alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - , , , )];
_refreshText.font = [UIFont fontWithName:@"Arial" size:];
_refreshText.textColor = [UIColor blackColor];
_refreshText.text = @"下拉刷新";
}
return _refreshText;
} //刷新旋转视图
- (UIActivityIndicatorView *)loadingIndicatorView
{
if (!_loadingIndicatorView) {
_loadingIndicatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - , , , )];
[_loadingIndicatorView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
_loadingIndicatorView.backgroundColor = [UIColor clearColor];
_loadingIndicatorView.center = CGPointMake(UISCREEN_WIDTH / 2.0 - , );
}
return _loadingIndicatorView;
} //设置三种刷新模式
- (void)setRefreshMode:(int)mode
{
switch (mode) {
case ://下拉过程中
{
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 ://提示松开刷新
{
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 ://松开后刷新
{
self.arrowView.hidden = YES;
self.loadingIndicatorView.hidden = NO;
[self.loadingIndicatorView startAnimating];
self.refreshText.text = @"正在刷新"; }
break; default:
break;
}
} @end

TableRefreshFooterView.h

#import <UIKit/UIKit.h>

@interface TableRefreshFooterView : UIView

@property(nonatomic, strong) UIActivityIndicatorView *loadingIndcatorView;

@property(nonatomic, strong) UILabel *loadingText;

- (void)setLoadingMode:(int)mode;

@end

TableRefreshFooterView.m

#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 - , , , )];
[_loadingIndcatorView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
_loadingIndcatorView.backgroundColor = [UIColor clearColor];
_loadingIndcatorView.center = CGPointMake(UISCREEN_WIDTH / 2.0 - , );
}
return _loadingIndcatorView;
} - (UILabel *)loadingText
{
if (!_loadingText) {
_loadingText = [[UILabel alloc]initWithFrame:CGRectMake(UISCREEN_WIDTH / 2.0 - , , , )];
_loadingText.font = [UIFont fontWithName:@"Arial" size:];
_loadingText.textColor = [UIColor blackColor];
_loadingText.text = @"加载中";
}
return _loadingText;
} - (void)setLoadingMode:(int)mode
{
switch (mode) {
case :
_loadingText.text = @"加载中";
[self.loadingIndcatorView startAnimating];
self.loadingIndcatorView.hidden = NO;
break;
case :
_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.h

#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.m

#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 = ;
isLoading = NO;
isRefreshing = NO;
drageMode = -;
[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(, , UISCREEN_WIDTH, UISCREEN_HEIGHT - )];
_myTableView.delegate = self;
_myTableView.dataSource = self;
}
return _myTableView;
} - (TableRefreshHeaderView *)refreshHeaderView
{
if (!_refreshHeaderView) {
_refreshHeaderView = [[TableRefreshHeaderView alloc]initWithFrame:CGRectMake(, -, UISCREEN_WIDTH, )];
}
return _refreshHeaderView;
} - (TableRefreshFooterView *)loadingFooterView
{
if (!_loadingFooterView) {
_loadingFooterView = [[TableRefreshFooterView alloc]initWithFrame:CGRectMake(, self.myTableView.contentSize.height, UISCREEN_WIDTH, )];
}
return _loadingFooterView;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return rowCount;
} - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return ;
} - (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+];
return cell;
} -(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
//如果列表控件加载完毕且当前为下拉加载,则将下拉加载视图移到列表可视范围之外
if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row && drageMode == ){
self.myTableView.contentInset = UIEdgeInsetsMake(, , , );
}
} //监听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(, self.myTableView.contentSize.height, UISCREEN_WIDTH, );
if (self.myTableView.isDragging) {
if (self.myTableView.contentOffset.y > -) {
[self.refreshHeaderView setRefreshMode:];
}
else if (self.myTableView.contentOffset.y < -)
{
[self.refreshHeaderView setRefreshMode:];
}
}
else
{
if (self.myTableView.contentOffset.y < -)
{
drageMode = ;
self.myTableView.contentInset = UIEdgeInsetsMake(, , , );
[self.refreshHeaderView setRefreshMode:];
[self beginRefresh];
}
else if (self.myTableView.contentOffset.y > self.myTableView.contentSize.height - self.myTableView.frame.size.height + )
{
drageMode = ;
if (rowCount < ) {
[self.loadingFooterView setLoadingMode:];
[self beginLoading];
}
else
{
[self.loadingFooterView setLoadingMode:];
self.myTableView.contentInset = UIEdgeInsetsMake(, , , );
}
}
}
}
} //开始刷新
- (void)beginRefresh
{
dispatch_async(dispatch_get_global_queue(, ), ^{
isRefreshing = YES;
sleep();//处理耗时操作
dispatch_async(dispatch_get_main_queue(), ^{
[self endRefresh];//处理完之后更新界面
});
}) ;
} //停止刷新
- (void)endRefresh
{
[UIView animateWithDuration:0.3 animations:^{
self.myTableView.contentInset = UIEdgeInsetsMake(, , , );
}];
[self.refreshHeaderView setRefreshMode:];
isRefreshing = NO;
} //开始加载
- (void)beginLoading
{
dispatch_async(dispatch_get_global_queue(, ), ^{
isLoading = YES;
rowCount += ;
self.myTableView.contentInset = UIEdgeInsetsMake(, , , );
sleep();//处理耗时操作
dispatch_async(dispatch_get_main_queue(), ^{
[self.myTableView reloadData];
[self endLoading];//处理完之后更新界面
});
}) ;
} //停止加载
- (void)endLoading
{
if (rowCount >= ) {
[self.loadingFooterView setLoadingMode:];
self.myTableView.contentInset = UIEdgeInsetsMake(, , , );
}
else
{
self.myTableView.contentInset = UIEdgeInsetsMake(, , , );
[self.loadingFooterView setLoadingMode:];
}
isLoading = NO;
} @end

源码下载地址:http://download.csdn.net/detail/lzm2625347497/9601843

IOS UITableView下拉刷新和上拉加载功能的实现的更多相关文章

  1. android--------自定义控件ListView实现下拉刷新和上拉加载

    开发项目过程中基本都会用到listView的下拉刷新和上滑加载更多,为了方便重写的ListView来实现下拉刷新,同时添加了上拉自动加载更多的功能. Android下拉刷新可以分为两种情况: 1.获取 ...

  2. IOS 开发下拉刷新和上拉加载更多

    IOS 开发下拉刷新和上拉加载更多 简介 1.常用的下拉刷新的实现方式 (1)UIRefreshControl (2)EGOTTableViewrefresh (3)AH3DPullRefresh ( ...

  3. 下拉刷新和上拉加载 Swift

    转载自:http://iyiming.me/blog/2015/07/05/custom-refresh-and-loading/ 关于下拉刷新和上拉加载,项目中一直使用MJRefresh(原先还用过 ...

  4. iOS下拉刷新和上拉刷新

    在iOS开发中,我们经常要用到下拉刷新和上拉刷新来加载新的数据,当前这也适合分页.iOS原生就带有该方法,下面就iOS自带的下拉刷新方法来简单操作. 上拉刷新 1.在TableView里,一打开软件, ...

  5. Android 5.X新特性之为RecyclerView添加下拉刷新和上拉加载及SwipeRefreshLayout实现原理

    RecyclerView已经写过两篇文章了,分别是Android 5.X新特性之RecyclerView基本解析及无限复用 和 Android 5.X新特性之为RecyclerView添加Header ...

  6. iscroll.js 下拉刷新和上拉加载

    html代码如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  7. Android 使用PullToRefresh实现下拉刷新和上拉加载(ExpandableListView)

    PullToRefresh是一套实现非常好的下拉刷新库,它支持: 1.ListView 2.ExpandableListView 3.GridView 4.WebView 等多种常用的需要刷新的Vie ...

  8. 使用PullToRefresh实现下拉刷新和上拉加载

    使用PullToRefresh实现下拉刷新和上拉加载 分类: Android2013-12-20 15:51 78158人阅读 评论(91) 收藏 举报 Android下拉刷新上拉加载PullToRe ...

  9. H5下拉刷新和上拉加载实现原理浅析

    前言 在移动端H5网页中,下拉刷新和上拉加载更多数据的交互方式出现频率很高,开源社区也有很多类似的解决方案,如iscroll,pulltorefresh.js库等.下面是对这两种常见交互基本实现原理的 ...

随机推荐

  1. RabbitMQ(四) -- Routing

    RabbitMQ(四) -- Routing `rabbitmq`可以通过路由选择订阅者来发布消息. Bindings 通过下面的函数绑定Exchange与消息队列: channel.queue_bi ...

  2. paip.前端加载时间分析之道优化最佳实践

    paip.前端加载时间分析之道优化最佳实践 1.另存为 ,查看文件尺寸..和图片. 2.view the 另存为的htm静态的文件单个的加载,看时间...可以排除编程语言的问题and 数据库.. ## ...

  3. iOS开发——高级技术&签名机制

    签名机制 最近看了objc.io上第17期中的文章 <Inside Code Signing> 对应的中文翻译版 <代码签名探析> ,受益颇深,对iOS代码签名机制有了进一步的 ...

  4. iOS开发---百度地图配置流程,2.6.0 版本 支持64位

      1.首先需要在百度地图下载最新SDK:地址: http://developer.baidu.com/map/index.php?title=iossdk/sdkiosdev-download 2. ...

  5. iOS开发——高级技术&通讯录功能的实现

    通讯录功能的实现 iOS 提供了对通讯录操作的组建,其中一个是直接操作通讯录,另一个是调用通讯录的 UI 组建.实现方法如下: 添加AddressBook.framework到工程中. 代码实现: 1 ...

  6. VS2015安装 Secondary Installer Setup Failed求解决方案

    个人同步本文博客地址http://aehyok.com/Blog/Detail/64.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章 ...

  7. (转)【Unity3d】Glow + Outline 轮廓描边

    转:http://www.cnblogs.com/dosomething/archive/2012/08/04/2622488.html [Unity3d]Glow + Outline 轮廓描边 轮廓 ...

  8. Spring3 整合MyBatis3 配置多数据源 动态选择SqlSessionFactory

    一.摘要 上两篇文章分别介绍了Spring3.3 整合 Hibernate3.MyBatis3.2 配置多数据源/动态切换数据源 方法 和 Spring3 整合Hibernate3.5 动态切换Ses ...

  9. 无线局域网络 WIFI/WAPI/WLAN区别浅析

    WIFI和WAPI的区别 既然WIFI和WAPI都是WLAN的传输协议,那么两者究竟都有怎样的区别? 首先第一点区别在于,两者的缔造者不一样.WIFI是又国外制定的一个协议,而WAPI是由中国制定的, ...

  10. 关于Domino数据库的软删除

    在Domino的数据库属性的 “高级” 附签(选择文件->数据库->属性),选中“允许软删除”,这样我们就启用了软删除功能,当一个文档没有删除的时候我们可以使用NotesDatabase的 ...