在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. MVC3不能正确识别JSON中的Enum枚举值

    一.背景 在MVC3项目里,如果Action的参数中有Enum枚举作为对象属性的话,使用POST方法提交过来的JSON数据中的枚举值却无法正确被识别对应的枚举值. 二.Demo演示 为了说明问题,我使 ...

  2. jenkins和docker 在docker里运行jenkins

    在docker里运行jenkins server. 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://github.com/ciandcd ...

  3. AdaBoost算法简介

    一.AdaBoost的损失函数 AdaBoost优化的是指数损失,即\begin{align*} \mathbb{E}_{\boldsymbol{x} \sim \mathfrak{D}, y}[e^ ...

  4. struts2学习笔记之四:多配置文件支持和常用配置参数

    struts2支持可以按照不同模块分类的方式拆分配置文件,支持多人分工合作,各自维护自己的配置文件,但是所有配置文件中包名和action的名称不能重复   struts2的配置文件方式有两种,stru ...

  5. 【Android】应用程序Activity启动过程分析

    在Android系统中,有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会为我们启动应用程序的主Activity:应用程序的默认Activity启动起来后,它又可以 ...

  6. atitit.提升开发效率---MDA 软件开发方式的革命(3)----自动化建表

    atitit.提升开发效率---MDA 软件开发方式的革命(3)----自动化建表 1. 建模在后自动建表 1 1. 传统上,需要首先建表,在业务编码.. 1 2. 模型驱动建表---更多简化法是在建 ...

  7. IOS设计模式浅析之工厂方法模式(Factory Method)

    概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...

  8. Android图片处理-图片压缩处理

    这里先重复温习一下上一篇,调用相册获取图片: /*** * 这个是调用android内置的intent,来过滤图片文件 ,同时也可以过滤其他的 */ Intent intent = new Inten ...

  9. 动软商城系统可免费下载了,专业批发分销商城系统,ASP.NET商城系统

    动软商城系统是一套集CMS资讯+品牌Shop商城+WAP商城+APP手机客户端+SNS用户互动社区于一体的全新电商营销解决方案.主要为企业树立企业品牌形象,实现独立网络推广,充分集成网站SEO.企业微 ...

  10. C# 串口操作 ---- 系列文章

    C# 串口操作系列(5)--通讯库雏形 通讯库雏形的建立. 串口通讯介绍的高级篇,介绍更高级的抽象,为扩展为通用的客户端通讯库做铺垫,扩展性的考虑,能支持任意类型的流设备. ... 2010-08-0 ...